mirror of
https://github.com/paul-nameless/tg
synced 2024-11-25 21:30:22 +00:00
Merge pull request #83 from paul-nameless/quote
Shell-escape file path passed to commands
This commit is contained in:
commit
53c2e9354f
4 changed files with 23 additions and 16 deletions
|
@ -54,7 +54,7 @@ docker run -it --rm tg
|
||||||
|
|
||||||
- `terminal-notifier` or other program for notifications (see configuration)
|
- `terminal-notifier` or other program for notifications (see configuration)
|
||||||
- `ffmpeg` to record voice msgs and upload videos correctly
|
- `ffmpeg` to record voice msgs and upload videos correctly
|
||||||
- [tdlib](https://tdlib.github.io/td/build.html?language=Python) - in case of incompatibility with built in package
|
- [tdlib](https://tdlib.github.io/td/build.html?language=Python) - in case of incompatibility with built in package.
|
||||||
For example, macOS:
|
For example, macOS:
|
||||||
```sh
|
```sh
|
||||||
brew install tdlib
|
brew install tdlib
|
||||||
|
@ -99,16 +99,16 @@ LOG_PATH = "~/.local/share/tg/"
|
||||||
# use your own, for example:
|
# use your own, for example:
|
||||||
TDLIB_PATH = "/usr/local/Cellar/tdlib/1.6.0/lib/libtdjson.dylib"
|
TDLIB_PATH = "/usr/local/Cellar/tdlib/1.6.0/lib/libtdjson.dylib"
|
||||||
|
|
||||||
# you can use any other notification cmd, it is simple python file which
|
# you can use any other notification cmd, it is simple python string which
|
||||||
# can format title, msg, subtitle and icon_path paramters
|
# can format title, msg, subtitle and icon_path paramters
|
||||||
# In these exapmle, kitty terminal is used and when notification is pressed
|
# In these exapmle, kitty terminal is used and when notification is pressed
|
||||||
# it will focus on the tab of running tg
|
# it will focus on the tab of running tg
|
||||||
NOTIFY_CMD = '/usr/local/bin/terminal-notifier -title "{title}" -subtitle "{subtitle}" -message "{msg}" -appIcon "{icon_path}" -sound default -execute \'/Applications/kitty.app/Contents/MacOS/kitty @ --to unix:/tmp/kitty focus-tab --no-response -m title:tg\''
|
NOTIFY_CMD = "/usr/local/bin/terminal-notifier -title {title} -subtitle {subtitle} -message {msg} -appIcon {icon_path} -sound default -execute '/Applications/kitty.app/Contents/MacOS/kitty @ --to unix:/tmp/kitty focus-tab --no-response -m title:tg'"
|
||||||
|
|
||||||
# You can use your own voice recording cmd but it's better to use default one.
|
# You can use your own voice recording cmd but it's better to use default one.
|
||||||
# The voice note must be encoded with the Opus codec, and stored inside an OGG
|
# The voice note must be encoded with the Opus codec, and stored inside an OGG
|
||||||
# container. Voice notes can have only a single audio channel.
|
# container. Voice notes can have only a single audio channel.
|
||||||
VOICE_RECORD_CMD = "ffmpeg -f avfoundation -i ':0' -c:a libopus -b:a 32k '{file_path}'"
|
VOICE_RECORD_CMD = "ffmpeg -f avfoundation -i ':0' -c:a libopus -b:a 32k {file_path}"
|
||||||
|
|
||||||
# You can customize chat and msg flags however you want.
|
# You can customize chat and msg flags however you want.
|
||||||
# By default words will be used for readability, but you can make
|
# By default words will be used for readability, but you can make
|
||||||
|
|
10
tg/config.py
10
tg/config.py
|
@ -31,17 +31,17 @@ TDLIB_VERBOSITY = 0
|
||||||
MAX_DOWNLOAD_SIZE = "10MB"
|
MAX_DOWNLOAD_SIZE = "10MB"
|
||||||
|
|
||||||
# TODO: check platform
|
# TODO: check platform
|
||||||
NOTIFY_CMD = "/usr/local/bin/terminal-notifier -title '{title}' -subtitle '{subtitle}' -message '{msg}' -appIcon '{icon_path}'"
|
NOTIFY_CMD = "/usr/local/bin/terminal-notifier -title {title} -subtitle {subtitle} -message {msg} -appIcon {icon_path}"
|
||||||
|
|
||||||
HELP_CMD = "less"
|
HELP_CMD = "less"
|
||||||
|
|
||||||
if _os_name == _linux:
|
if _os_name == _linux:
|
||||||
VOICE_RECORD_CMD = (
|
VOICE_RECORD_CMD = (
|
||||||
"ffmpeg -f alsa -i default -c:a libopus -b:a 32k '{file_path}'"
|
"ffmpeg -f alsa -i default -c:a libopus -b:a 32k {file_path}"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
VOICE_RECORD_CMD = (
|
VOICE_RECORD_CMD = (
|
||||||
"ffmpeg -f avfoundation -i ':0' -c:a libopus -b:a 32k '{file_path}'"
|
"ffmpeg -f avfoundation -i ':0' -c:a libopus -b:a 32k {file_path}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: use mailcap instead of editor
|
# TODO: use mailcap instead of editor
|
||||||
|
@ -49,9 +49,9 @@ LONG_MSG_CMD = "vim + -c 'startinsert' {file_path}"
|
||||||
EDITOR = os.environ.get("EDITOR", "vi")
|
EDITOR = os.environ.get("EDITOR", "vi")
|
||||||
|
|
||||||
if _os_name == _linux:
|
if _os_name == _linux:
|
||||||
DEFAULT_OPEN = "xdg-open '{file_path}'"
|
DEFAULT_OPEN = "xdg-open {file_path}"
|
||||||
else:
|
else:
|
||||||
DEFAULT_OPEN = "open '{file_path}'"
|
DEFAULT_OPEN = "open {file_path}"
|
||||||
|
|
||||||
if _os_name == _linux:
|
if _os_name == _linux:
|
||||||
COPY_CMD = "xclip -selection c"
|
COPY_CMD = "xclip -selection c"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import curses
|
import curses
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import shlex
|
||||||
import threading
|
import threading
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import partial, wraps
|
from functools import partial, wraps
|
||||||
|
@ -91,7 +92,7 @@ class Controller:
|
||||||
return
|
return
|
||||||
if len(urls) == 1:
|
if len(urls) == 1:
|
||||||
with suspend(self.view) as s:
|
with suspend(self.view) as s:
|
||||||
s.call(config.DEFAULT_OPEN.format(file_path=url))
|
s.call(config.DEFAULT_OPEN.format(file_path=shlex.quote(url)))
|
||||||
return
|
return
|
||||||
with suspend(self.view) as s:
|
with suspend(self.view) as s:
|
||||||
s.run_with_input(config.URL_VIEW, "\n".join(urls))
|
s.run_with_input(config.URL_VIEW, "\n".join(urls))
|
||||||
|
@ -224,7 +225,7 @@ class Controller:
|
||||||
) as s:
|
) as s:
|
||||||
f.write(insert_replied_msg(msg))
|
f.write(insert_replied_msg(msg))
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
s.call(config.LONG_MSG_CMD.format(file_path=f.name))
|
s.call(config.LONG_MSG_CMD.format(file_path=shlex.quote(f.name)))
|
||||||
with open(f.name) as f:
|
with open(f.name) as f:
|
||||||
if msg := strip_replied_msg(f.read().strip()):
|
if msg := strip_replied_msg(f.read().strip()):
|
||||||
self.tg.reply_message(chat_id, reply_to_msg, msg)
|
self.tg.reply_message(chat_id, reply_to_msg, msg)
|
||||||
|
@ -251,7 +252,7 @@ class Controller:
|
||||||
with NamedTemporaryFile("r+", suffix=".txt") as f, suspend(
|
with NamedTemporaryFile("r+", suffix=".txt") as f, suspend(
|
||||||
self.view
|
self.view
|
||||||
) as s:
|
) as s:
|
||||||
s.call(config.LONG_MSG_CMD.format(file_path=f.name))
|
s.call(config.LONG_MSG_CMD.format(file_path=shlex.quote(f.name)))
|
||||||
with open(f.name) as f:
|
with open(f.name) as f:
|
||||||
if msg := f.read().strip():
|
if msg := f.read().strip():
|
||||||
self.model.send_message(text=msg)
|
self.model.send_message(text=msg)
|
||||||
|
@ -301,7 +302,11 @@ class Controller:
|
||||||
def record_voice(self):
|
def record_voice(self):
|
||||||
file_path = f"/tmp/voice-{datetime.now()}.oga"
|
file_path = f"/tmp/voice-{datetime.now()}.oga"
|
||||||
with suspend(self.view) as s:
|
with suspend(self.view) as s:
|
||||||
s.call(config.VOICE_RECORD_CMD.format(file_path=file_path))
|
s.call(
|
||||||
|
config.VOICE_RECORD_CMD.format(
|
||||||
|
file_path=shlex.quote(file_path)
|
||||||
|
)
|
||||||
|
)
|
||||||
resp = self.view.status.get_input(
|
resp = self.view.status.get_input(
|
||||||
f"Do you want to send recording: {file_path}? [Y/n]"
|
f"Do you want to send recording: {file_path}? [Y/n]"
|
||||||
)
|
)
|
||||||
|
|
|
@ -74,7 +74,7 @@ def get_file_handler(file_path, default=None):
|
||||||
caps = mailcap.getcaps()
|
caps = mailcap.getcaps()
|
||||||
handler, view = mailcap.findmatch(caps, mtype, filename=file_path)
|
handler, view = mailcap.findmatch(caps, mtype, filename=file_path)
|
||||||
if not handler:
|
if not handler:
|
||||||
return config.DEFAULT_OPEN.format(file_path=file_path)
|
return config.DEFAULT_OPEN.format(file_path=shlex.quote(file_path))
|
||||||
return handler
|
return handler
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,9 +148,11 @@ def notify(
|
||||||
if not cmd:
|
if not cmd:
|
||||||
return
|
return
|
||||||
notify_cmd = cmd.format(
|
notify_cmd = cmd.format(
|
||||||
icon_path=config.ICON_PATH, title=title, subtitle=subtitle, msg=msg
|
icon_path=shlex.quote(config.ICON_PATH),
|
||||||
|
title=shlex.quote(title),
|
||||||
|
subtitle=shlex.quote(subtitle),
|
||||||
|
msg=shlex.quote(msg),
|
||||||
)
|
)
|
||||||
log.info("notify-cmd: %s", notify_cmd)
|
|
||||||
os.system(notify_cmd)
|
os.system(notify_cmd)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue