The code is organized into following focused modules:
- Command-line argument parsing
- Application initialization
- Version handling
- Authentication setup (token, basic, cookie)
- Macro loading
- Entry point that calls
run()from client module
Key functions:
exception_hook()- Crash handlerif __name__ == '__main__'- Main entry point
- Helper functions and data structures
- File/image processing utilities
- Encoding and parsing functions
Key functions:
dotdict- Dictionary with dot notation accessmakeTheCard()- Pack user profile datainline_image()- Create drafty image messagesattachment()- Create drafty attachment messagesencode_to_bytes()- Convert objects to bytesparse_cred()- Parse credentialsparse_trusted()- Parse trusted values
Constants:
MAX_INBAND_ATTACHMENT_SIZEMAX_EXTERN_ATTACHMENT_SIZEMAX_IMAGE_DIMDELETE_MARKERTINODE_DEL
- Command-line parsing for all commands
- Protobuf message construction
- Variable dereferencing
- Command serialization
Key functions:
parse_input()- Parse command line inputparse_cmd()- Create argument parsersserialize_cmd()- Convert commands to protobufderefVals()/getVar()- Variable dereferencing- Message builders:
hiMsg(),accMsg(),loginMsg(),subMsg(),leaveMsg(),pubMsg(),getMsg(),setMsg(),delMsg(),noteMsg() - File operations:
upload(),fileUpload(),fileDownload() print_server_params()- Log server info
- gRPC connection management
- Message generation and streaming
- Server response handling
- Login/authentication handling
- Cookie management
Key functions:
run()- Main client loopgen_message()- Generate outgoing messageshandle_ctrl()- Handle server control responseshandle_login()- Process login responsesave_cookie()/read_cookie()- Cookie persistencepop_from_output_queue()- Output queue management
- Terminal input reading
- Multi-line input support
- Interactive and non-interactive modes
Key functions:
stdin()- Main input loopreadLinesFromStdin()- Read with prompt support
- Global variables shared across all modules
- Asynchronous I/O queue management
- Utility functions for logging and output
- Protobuf to JSON conversion
Key variables:
OnCompletion- Dictionary of callbacks for server responsesWaitingFor- Outstanding synchronous command requestAuthToken- Current authentication tokenInputQueue/OutputQueue- Async I/O queuesInputThread- Background input threadIsInteractive- Detect if running in interactive modePrompt- PromptSession for interactive inputDefaultUser/DefaultTopic- Default context valuesVariables- Store command execution resultsConnection- gRPC connection to serverVerbose- Extended logging flag
Key functions:
printout()- Print in interactive mode onlyprinterr()- Write to stderrstdout()/stdoutln()- Async output to stdoutclip_long_string()- Shorten long strings for loggingto_json()- Convert protobuf messages to JSON
- High-level command macros that expand into basic commands
- Simplifies complex multi-step operations
- Requires root privileges for most operations
Macro base class:
Macro- Base class for all macros with parsing and execution
Available macros:
usermod- Modify user account (suspend/unsuspend, update theCard, trusted values)resolve- Resolve login name to user IDpasswd- Set user's passworduseradd- Create new user account with credentialschacs- Change default permissions/acs for a useruserdel- Delete user account (soft or hard delete)chcred- Add/delete/validate user credentialsthecard- Print user's public/private data or credentials
Key functions:
parse_macro()- Find parser for macro commandMacro.expand()- Expand macro to list of basic commandsMacro.run()- Execute macro or explain expansion
Macro dictionary:
Macros- Dictionary mapping macro names to instances
tn-cli.py
├── tn_globals
├── client (run, read_cookie)
└── commands (set_macros_module)
client.py
├── tn_globals
├── tinode_grpc (pb, pbx)
├── utils (dotdict)
├── input_handler (stdin)
└── commands (hiMsg, loginMsg, serialize_cmd)
commands.py
├── tn_globals
├── tinode_grpc (pb, pbx)
├── utils (makeTheCard, inline_image, attachment, etc.)
└── client (handle_ctrl, handle_login, save_cookie) [for specific commands]
utils.py
├── tn_globals
└── tinode_grpc (pb)
input_handler.py
└── tn_globals
macros.py
└── tn_globals
tn_globals.py
└── (no dependencies - provides shared state)
- Separation of Concerns: Each module has a clear, focused responsibility
- Maintainability: Easier to find and modify specific functionality
- Testability: Individual modules can be tested independently
- Readability: Smaller files are easier to understand
- Reusability: Utilities and client code can be reused
- Extensibility: Easy to add new macros or commands without modifying core logic
- Shared State Management:
tn_globals.pyprovides centralized state accessible to all modules
Run the application using:
python3 tn-cli.py [arguments]Or make it executable:
chmod +x tn-cli.py
./tn-cli.py [arguments]