profile
viewpoint

paul-nameless/tg 179

terminal telegram client that really works

lightme16/vk-audio-downloader 4

Simpe script to downloads music from your vk.com account

lightme16/react-game-of-life 1

Conway's Game of Life implementation using React. https://codepen.io/BassJuzz/full/wXQNrR/

lightme16/aioelasticsearch 0

aioelasticsearch-py wrapper for asyncio

lightme16/aiohttp_babel 0

Babel localisation support for aiohttp

lightme16/Automatic_email_spam_processor 0

This script will helps you automate your daily routine work with classification of spam letter in mailbox. Comparable with Gmail, Yahoo and Outlook.

lightme16/bootcamp 0

An enterprise social network

lightme16/cheap-visa-site 0

Landing page for small business

lightme16/coding-interview-university 0

A complete computer science study plan to become a software engineer.

PullRequestReviewEvent

Pull request review commentpaul-nameless/tg

Mark msgs as viewed when sent new msg

 def send_message(self, text: str) -> bool:         chat_id = self.chats.id_by_index(self.current_chat)         if chat_id is None:             return False+        # order is matter: this should be before send_message+        # otherwise it vill view message that was sent

typo -> will

paul-nameless

comment created time in 5 days

PullRequestReviewEvent
PullRequestReviewEvent

starteddanistefanovic/build-your-own-x

started time in 11 days

startedUnitedIncome/serverless-python-requirements

started time in 18 days

startedprompt-toolkit/ptpython

started time in 18 days

startedpimutils/vdirsyncer

started time in a month

startedpimutils/khal

started time in a month

push eventpaul-nameless/tg

Nameless

commit sha 859de4a6d368d5574464186bdc5e25eea5dd7f56

Fix hang when opened external app and resizing terminal (#167)

view details

push time in 2 months

delete branch paul-nameless/tg

delete branch : fix-hang

delete time in 2 months

PR merged paul-nameless/tg

Fix hang when opened external app and resizing terminal

Reproduce:

  1. Open any chat
  2. Open external program, e.g. vim to enter long msg
  3. Resize terminal

Now everything will be hung and the only way is to kill it

+12 -4

0 comment

3 changed files

paul-nameless

pr closed time in 2 months

Pull request review commentpaul-nameless/tg

Fix hang when opened external app and resizing terminal

 def __init__(         self.msgs = msg_view         self.status = status_view         self.max_read = 2048+        self.resize_handler = self.resize++    def resize_mock(self) -> None:

so, resize_mock -> resize_stub

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Fix hang when opened external app and resizing terminal

 def __init__(         self.msgs = msg_view         self.status = status_view         self.max_read = 2048+        self.resize_handler = self.resize++    def resize_mock(self) -> None:

it is a stub, not mock 🙂

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show chat info with <c> shortcut in msg panel

 def copy_msgs_text(self) -> bool:         copy_to_clipboard("\n".join(buffer))         return True +    def get_chat_info(self, chat: Dict[str, Any]) -> Dict[str, Any]:

this function looks too long, i suggest split it.

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show chat info with <c> shortcut in msg panel

 def copy_msgs_text(self) -> bool:         copy_to_clipboard("\n".join(buffer))         return True +    def get_chat_info(self, chat: Dict[str, Any]) -> Dict[str, Any]:+        chat_type = get_chat_type(chat)+        if chat_type is None:+            return {}++        info = {}++        if chat_type == ChatType.chatTypePrivate:+            user_id = chat["id"]+            user = self.users.get_user(user_id)+            user_info = self.users.get_user_full_info(user_id)+            status = self.users.get_status(user_id)+            info.update(+                {+                    chat["title"]: status,+                    "Username": user.get("username", ""),+                    "Phone": user.get("phone_number", ""),+                    "Bio": user_info.get("bio", ""),+                }+            )++        if chat_type == ChatType.chatTypeBasicGroup:+            group_id = chat["type"]["basic_group_id"]+            result = self.tg.get_basic_group_full_info(group_id)+            result.wait()

not directly related to this PR, but the way we calls tdlib is urly:

result = self.tg.get_basic_group_full_info(group_id)
result.wait()
chat_info = result.update

we can have much better way of doing it, without wasting 2 lines for each tdlib call: chat_info = self.tg.get_basic_group_full_info(group_id)

our tdlib module should hide this complicity

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show chat info with <c> shortcut in msg panel

 def copy_msgs_text(self) -> bool:         copy_to_clipboard("\n".join(buffer))         return True +    def get_chat_info(self, chat: Dict[str, Any]) -> Dict[str, Any]:+        chat_type = get_chat_type(chat)+        if chat_type is None:+            return {}++        info = {}++        if chat_type == ChatType.chatTypePrivate:+            user_id = chat["id"]+            user = self.users.get_user(user_id)+            user_info = self.users.get_user_full_info(user_id)+            status = self.users.get_status(user_id)+            info.update(+                {+                    chat["title"]: status,+                    "Username": user.get("username", ""),+                    "Phone": user.get("phone_number", ""),+                    "Bio": user_info.get("bio", ""),+                }+            )++        if chat_type == ChatType.chatTypeBasicGroup:

why aren't you use elif? it will improve readability a bit

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show chat info with <c> shortcut in msg panel

 def __init__(self, model: Model, view: View, tg: Tdlib) -> None:         self.tg = tg         self.chat_size = 0.5 +    @bind(msg_handler, ["c"])

Why does the shortcut attached to the msg_handler? I believe it should be in chat_handlers. We can use i(stands from information) shortcut for chat panel.

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Fix drawing glitch with chat vertical separator

 def notify(     subprocess.Popen(notify_cmd, shell=True)  -def truncate_to_len(s: str, target_len: int) -> str:-    target_len -= sum(map(bool, map(emoji_pattern.findall, s[:target_len])))-    return s[: max(1, target_len - 1)]+def string_len_dwc(string: str) -> int:+    """Returns string len including count for double width characters"""+    return sum(1 + (unicodedata.east_asian_width(c) in "WF") for c in string)+++def truncate_to_len(string: str, width: int) -> str:+    real_len = string_len_dwc(string)+    if real_len <= width:+        return string

this lines look redundant, do we really need them?

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Fix drawing glitch with chat vertical separator

 def notify(     subprocess.Popen(notify_cmd, shell=True)  -def truncate_to_len(s: str, target_len: int) -> str:-    target_len -= sum(map(bool, map(emoji_pattern.findall, s[:target_len])))-    return s[: max(1, target_len - 1)]+def string_len_dwc(string: str) -> int:+    """Returns string len including count for double width characters"""+    return sum(1 + (unicodedata.east_asian_width(c) in "WF") for c in string)+++def truncate_to_len(string: str, width: int) -> str:+    real_len = string_len_dwc(string)+    if real_len <= width:+        return string++    cur_len = 0+    out_string = ""++    for char in string:+        cur_len += 2 if unicodedata.east_asian_width(char) in "WF" else 1+        if cur_len < width:+            out_string += char

else: break ?

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show user info

 def get_user_full_info(self, user_id: int) -> Dict[str, Any]:         if user.get("full_info"):             return user["full_info"] -        result = self.tg.get_user_full_info(user_id, block=True)+        result = self.tg.get_user_full_info(user_id,)

redundant ,

paul-nameless

comment created time in 2 months

pull request commentpaul-nameless/tg

Change AUR package to version following releases

Ok. cool, thanks!

jugendhacker

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show user info

 def get_user(self, user_id: int) -> AsyncResult:         }         return self._send_data(data) -    def get_user_full_info(self, user_id: int) -> AsyncResult:+    def get_user_full_info(+        self, user_id: int, block: bool = False

**kwargs - that is unneeded complications. .wait() - we don't need to bloat client's code with this. YAGNI. let's add stuff when we really need it. let's not solve imaginary problems

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show user info

 def get_user(self, user_id: int) -> AsyncResult:         }         return self._send_data(data) -    def get_user_full_info(self, user_id: int) -> AsyncResult:+    def get_user_full_info(+        self, user_id: int, block: bool = False

we don't need block as argument here. we will always use it with True

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show user info

 def __init__(self, model: Model, view: View, tg: Tdlib) -> None:         self.tg = tg         self.chat_size = 0.5 +    @bind(msg_handler, ["u"])+    def user_innfo(self) -> None:

can we show link to user's avatar as well?

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show user info

 def is_online(self, user_id: int) -> bool:             return True         return False +    def get_user_full_info(self, user_id: int) -> Dict[str, Any]:+        user = self.get_user(user_id)+        if not user:+            return user+        if user.get("full_info"):+            return user["full_info"]++        result = self.tg.get_user_full_info(user_id)+        result.wait()

tip: instead of doing pretty ugly wait() in caller's code you can and block=True to tdlib call. See https://github.com/paul-nameless/tg/blob/50b93eb3087c02af689246ba4816e1ebda31dc6f/tg/tdlib.py#L118

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Create directory for logs if missing

         if param.isupper():             globals()[param] = value else:-    for directory in (LOG_PATH, CONFIG_DIR, FILES_DIR):

what about FILES_DIR?

paul-nameless

comment created time in 2 months

pull request commentpaul-nameless/tg

Change AUR package to version following releases

@jugendhacker I've added setup.py. So, you should be able to stop using dephell in both AURs. Could you plz check it out?

jugendhacker

comment created time in 2 months

issue openedpaul-nameless/tg

Remove flit

https://github.com/paul-nameless/tg/pull/155#issuecomment-662199443

created time in 2 months

pull request commentpaul-nameless/tg

Add phone number information

Also, let's create log file dir if it is missing as per https://github.com/paul-nameless/tg/issues/148#issuecomment-662258752

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Add phone number information

 Config file should be stored at `~/.config/tg/conf.py`. This is simple python fi ### Simple config:  ```python-PHONE = "[your phone number]"+# should start with + (plus) and contain country code+PHONE = "[phone number in international format]"

maybe let's add reexp to validate bad phone number?

paul-nameless

comment created time in 2 months

pull request commentpaul-nameless/tg

add setup.py

@paul-nameless ok

lightme16

comment created time in 2 months

push eventpaul-nameless/tg

lightme16

commit sha 905aa28ece2682ad548b84df04ae67e3bbdb9d24

respond to comments

view details

push time in 2 months

Pull request review commentpaul-nameless/tg

Implement creating new group and secret chat ( #150)

 def edit_msg(self) -> None:                     self.model.edit_message(text=text)                     self.present_info("Message edited") +    def _get_user_ids(self, is_multiple: bool = False) -> List[int]:+        users = self.model.users.get_list_of_users()+        _, cols = self.view.stdscr.getmaxyx()+        limit = min(int(cols / 2), max(len(user.name) for user in users),)+        users_out = "\n".join(+            f"{user.id}\t{user.name:<{limit}} | {user.status}"+            for user in sorted(users, key=lambda user: user.order)+        )+        cmd = config.FZF + " -n 2"

let's test that fzf exists before running this command. if it is missing we need to present meaningful msgs in status line

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Implement creating new group and secret chat ( #150)

 def edit_msg(self) -> None:                     self.model.edit_message(text=text)                     self.present_info("Message edited") +    def _get_user_ids(self, is_multiple: bool = False) -> List[int]:+        users = self.model.users.get_list_of_users()+        _, cols = self.view.stdscr.getmaxyx()+        limit = min(int(cols / 2), max(len(user.name) for user in users),)+        users_out = "\n".join(+            f"{user.id}\t{user.name:<{limit}} | {user.status}"+            for user in sorted(users, key=lambda user: user.order)+        )+        cmd = config.FZF + " -n 2"+        if is_multiple:+            cmd += " -m"++        with NamedTemporaryFile("r+") as tmp, suspend(self.view) as s:+            s.run_with_input(f"{cmd} > {tmp.name}", users_out)+            with open(tmp.name) as f:+                return [int(line.split()[0]) for line in f.readlines()]++    @bind(chat_handler, ["ns"])+    def new_secret(self) -> None:

Plz add function annotation to make it visible in help page

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Implement creating new group and secret chat ( #150)

 def get_contacts(self) -> Optional[Dict[str, Any]]:             return None         self.contacts = result.update         return self.contacts++    def get_user_label(self, user_id: int) -> str:+        if user_id == 0:+            return ""+        user = self.get_user(user_id)+        if user["first_name"] and user["last_name"]:+            return f'{user["first_name"]} {user["last_name"]}'[:20]++        if user["first_name"]:+            return f'{user["first_name"]}'[:20]++        if user.get("username"):+            return "@" + user["username"]+        return "<Unknown>"++    def get_list_of_users(self) -> List[User]:

get_user_list or get_users will be a better name.

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Implement creating new group and secret chat ( #150)

     "sp",     "sa",     "sv",+    "ns",+    "nc",

"nc" & "np" - where is it used?

paul-nameless

comment created time in 2 months

issue commentpaul-nameless/tg

Arch: various crashes on first run

I think we should still create missing log dir if config file already exists to avoid such problems in future.

classabbyamp

comment created time in 2 months

pull request commentpaul-nameless/tg

add setup.py

@paul-nameless we can use twine to upload to pypi, see

lightme16

comment created time in 2 months

pull request commentpaul-nameless/tg

Change AUR package to version following releases

Looks great, however let's wait for https://github.com/paul-nameless/tg/pull/155 merge. After that we can drop dephell support from both AURs.

jugendhacker

comment created time in 2 months

push eventpaul-nameless/tg

lightme16

commit sha de4c97f7bc9e4a32fba309a93c9d1ebf1e210e6a

add setup.py

view details

push time in 2 months

PR opened paul-nameless/tg

add setup.py
  • use setuptool instead of flit to remove flit as extra dependency during packaging
+27 -24

0 comment

3 changed files

pr created time in 2 months

create barnchpaul-nameless/tg

branch : add-setup-py

created branch time in 2 months

push eventpaul-nameless/tg

Nicola Stanislao Vitale

commit sha 58927d73ef222b5f771cac1163dce4cad71ed51a

Fix typos (#154)

view details

push time in 2 months

PR merged paul-nameless/tg

Fix typos
+2 -2

0 comment

1 changed file

nivit

pr closed time in 2 months

Pull request review commentpaul-nameless/tg

Disable text formatting which uses tdlib (it is not implemented as in desktop clients)

 def parse_text_entities(     def send_message(self, chat_id: int, msg: str) -> AsyncResult:         text = {"@type": "formattedText", "text": msg} -        result = self.parse_text_entities(msg)-        result.wait()-        if not result.error:-            text = result.update+        # TODO: implement your own parse entities like in tdlib

TBH I would live this feature as it. It is usable to me.

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Use the __main__.py special filename for main.py

 TODO: - [ ] create new chat - [ ] bots (bot keyboard) +## Requirements -## Installation+To use tg, you'll need to have the following installed:++- [Python 3.8](https://www.python.org/downloads/release/python-380/)++## Optional dependencies++- [terminal-notifier](https://github.com/julienXX/terminal-notifier) for Mac (used by default). You can change it to [dunst](https://github.com/dunst-project/dunst) for Linux or any other notifications program (see `NOTIFY_CMD` in configuration)+- [ffmpeg](https://ffmpeg.org/) to record voice msgs and upload videos.+- [tdlib](https://tdlib.github.io/td/build.html?language=Python) - in case of incompatibility with built in package.+  For example, macOS:+  ```sh+  brew install tdlib+  ```+  and then set in config `TDLIB_PATH`+- `urlview` to choose urls when there is multiple in message, use `URL_VIEW` in config file to use another app (it should accept urls in stdin)+- to open `stickers` and `animated` ones (thumbnail preview) you need to set in mailcap appropriate handler and have app which will open `webp` file:+  ```ini+  image/webp; mpv %s+  ``` -`python3.8` required.+## Installation +### From PyPI -From pip:+This option is recommended for production:  ```sh pip3 install tg+tg ``` -From sources:+### Using flit++This option is recommended for development:++> Requires [flit](https://github.com/takluyver/flit) to be installed.+>+> Install it with:+> ```sh +> pip3 install flit+> ```  ```sh-pip3 install python-telegram-git clone git@github.com:paul-nameless/tg.git+git clone https://github.com:paul-nameless/tg.git cd tg-PYTHONPATH=. python3 tg/main.py+flit install+tg ``` -Docker (voice recordings and notifications won't work):+### Without installing

So, so let use Running with virtualenv then?

Steffo99

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Use the __main__.py special filename for main.py

 TODO: - [ ] create new chat - [ ] bots (bot keyboard) +## Requirements -## Installation+To use tg, you'll need to have the following installed:++- [Python 3.8](https://www.python.org/downloads/release/python-380/)++## Optional dependencies++- [terminal-notifier](https://github.com/julienXX/terminal-notifier) for Mac (used by default). You can change it to [dunst](https://github.com/dunst-project/dunst) for Linux or any other notifications program (see `NOTIFY_CMD` in configuration)+- [ffmpeg](https://ffmpeg.org/) to record voice msgs and upload videos.+- [tdlib](https://tdlib.github.io/td/build.html?language=Python) - in case of incompatibility with built in package.+  For example, macOS:+  ```sh+  brew install tdlib+  ```+  and then set in config `TDLIB_PATH`+- `urlview` to choose urls when there is multiple in message, use `URL_VIEW` in config file to use another app (it should accept urls in stdin)+- to open `stickers` and `animated` ones (thumbnail preview) you need to set in mailcap appropriate handler and have app which will open `webp` file:+  ```ini+  image/webp; mpv %s+  ``` -`python3.8` required.+## Installation +### From PyPI -From pip:+This option is recommended for production:  ```sh pip3 install tg+tg ``` -From sources:+### Using flit++This option is recommended for development:++> Requires [flit](https://github.com/takluyver/flit) to be installed.+>+> Install it with:+> ```sh +> pip3 install flit+> ```  ```sh-pip3 install python-telegram-git clone git@github.com:paul-nameless/tg.git+git clone https://github.com:paul-nameless/tg.git cd tg-PYTHONPATH=. python3 tg/main.py+flit install+tg ``` -Docker (voice recordings and notifications won't work):+### Without installing

Without installing -> Using virtualenv would be better naming

Steffo99

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Use the __main__.py special filename for main.py

 TODO: - [ ] create new chat - [ ] bots (bot keyboard) +## Requirements -## Installation+To use tg, you'll need to have the following installed:++- [Python 3.8](https://www.python.org/downloads/release/python-380/)++## Optional dependencies++- [terminal-notifier](https://github.com/julienXX/terminal-notifier) for Mac (used by default). You can change it to [dunst](https://github.com/dunst-project/dunst) for Linux or any other notifications program (see `NOTIFY_CMD` in configuration)+- [ffmpeg](https://ffmpeg.org/) to record voice msgs and upload videos.+- [tdlib](https://tdlib.github.io/td/build.html?language=Python) - in case of incompatibility with built in package.+  For example, macOS:+  ```sh+  brew install tdlib+  ```+  and then set in config `TDLIB_PATH`+- `urlview` to choose urls when there is multiple in message, use `URL_VIEW` in config file to use another app (it should accept urls in stdin)+- to open `stickers` and `animated` ones (thumbnail preview) you need to set in mailcap appropriate handler and have app which will open `webp` file:+  ```ini+  image/webp; mpv %s+  ``` -`python3.8` required.+## Installation +### From PyPI -From pip:+This option is recommended for production:  ```sh pip3 install tg+tg ``` -From sources:+### Using flit++This option is recommended for development:++> Requires [flit](https://github.com/takluyver/flit) to be installed.+>+> Install it with:+> ```sh +> pip3 install flit+> ```  ```sh-pip3 install python-telegram-git clone git@github.com:paul-nameless/tg.git+git clone https://github.com:paul-nameless/tg.git cd tg-PYTHONPATH=. python3 tg/main.py+flit install+tg ``` -Docker (voice recordings and notifications won't work):+### Without installing++> Ensure you have the correct version of Python installed before using this method!+ ```sh-docker run -it --rm tg+git clone https://github.com:paul-nameless/tg.git+cd tg+python3 -m venv venv+source venv/bin/activate+pip install python-telegram+python3 tg/__main__.py

why aren't you using python3 -m tg here? I think idea of this PR was so allow using such way of running a module :slightly_smiling_face:

Steffo99

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Use the __main__.py special filename for main.py

 TODO:  ## Installation -`python3.8` required.---From pip:+### From PyPI  ```sh pip3 install tg+tg ``` -From sources:+### Using the GitHub sources ++> Requires [flit](https://github.com/takluyver/flit) to be installed.+>+> Install it with:+> ```sh +> pip3 install flit+> ```  ```sh-pip3 install python-telegram git clone git@github.com:paul-nameless/tg.git cd tg-PYTHONPATH=. python3 tg/main.py

i think it is still worth to mention about pip3 install python-telegram & python3 -m tg method. because you don't required to install flit to use tg client

Steffo99

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Use the __main__.py special filename for main.py

 From sources: pip3 install python-telegram git clone git@github.com:paul-nameless/tg.git cd tg-PYTHONPATH=. python3 tg/main.py+PYTHONPATH=. +python3 tg/main.py

agree, it is worth to add this to README. it will make life easier for people who will be adding brew package and others

Steffo99

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Use the __main__.py special filename for main.py

 TODO:  ## Installation -`python3.8` required.

why did you delete this? it is worth to mention that python 3.8 is required. e.g it won't work with python3.7 and lower

Steffo99

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Use the __main__.py special filename for main.py

 TODO:  ## Installation -`python3.8` required.---From pip:+### From PyPI  ```sh pip3 install tg tg ``` -From sources:+### Using the GitHub sources ++> Requires [flit](https://github.com/takluyver/flit) to be installed.+>+> Install it with:+> ```sh +> pip3 install flit+> ```  ```sh-pip3 install python-telegram git clone git@github.com:paul-nameless/tg.git cd tg-PYTHONPATH=. -python3 tg/main.py+flit install+tg ``` -Docker (voice recordings and notifications won't work):+### Using Docker++> Please note that voice recordings and notifications won't work when using Docker.+ ```sh docker run -it --rm tg ``` -Arch Linux users can install from the AUR: https://aur.archlinux.org/packages/telegram-tg-git/+### From the AUR++If you're using Arch Linux, you can install tg through [its AUR package](https://aur.archlinux.org/packages/telegram-tg-git/):  ```bash-yay -S telegram-tg-git+pacman -S telegram-tg-git

that's wrong command, it will work only for packages in the official repo.

Steffo99

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Add ability to delete chat

 def num(value: str, default: Optional[int] = None) -> Optional[int]:         return default  -def is_yes(resp: Optional[str]) -> bool:-    if not resp or resp.strip().lower() == "y":-        return True-    return False+def is_yes(resp: str) -> bool:+    return not resp or resp.strip().lower() == "y"

I see, ok!

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Add ability to delete chat

 def num(value: str, default: Optional[int] = None) -> Optional[int]:         return default  -def is_yes(resp: Optional[str]) -> bool:-    if not resp or resp.strip().lower() == "y":-        return True-    return False+def is_yes(resp: str) -> bool:+    return not resp or resp.strip().lower() == "y"

having not resp does not make sense for resp: str, return resp.strip().lower() == "y" should be enough

paul-nameless

comment created time in 2 months

create barnchpaul-nameless/tg

branch : search-msgs

created branch time in 2 months

Pull request review commentpaul-nameless/tg

Do not draw status panel: it conflicts with another thread

 def render(self) -> None:     def _render(self) -> None:         self._render_chats()         self._render_msgs()-        self._render_status()+        # self._render_status()

plz, remove whole line, instead of commenting it.

also, let's put status clean up here https://github.com/paul-nameless/tg/pull/136/files/147e991ca39864b127e2e638aabb666b694a943b#diff-d44e7f685a07442bfcb2ff6f977897a3R336

paul-nameless

comment created time in 2 months

push eventpaul-nameless/tg

Nameless

commit sha 3d682441f25664efe334abd0c031aaee91f96788

Fix sending msg: fallback to simple text when failed to parse entities (#147) * Fix sending msg: fallback to simple text when failed to parse entities * Fix black formatting

view details

push time in 2 months

delete branch paul-nameless/tg

delete branch : fix-sending-msg

delete time in 2 months

Pull request review commentpaul-nameless/tg

Add ability to delete chat

 def edit_msg(self) -> None:                     self.model.edit_message(text=text)                     self.present_info("Message edited") +    @bind(chat_handler, ["dd"])+    def leave_chat(self) -> None:+        """Leave group or cloase private, secret chat"""+        # can_be_deleted_only_for_self+        # can_be_deleted_for_all_users+        chat = self.model.chats.chats[self.model.current_chat]+        resp = self.view.status.get_input(+            "Are you sure you want to delete the chat?[y/N]"+        )+        if resp is None or is_no(resp):

ok, but is_no(resp) would be enough, because is_no is able to work with None, isn't it?

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Add ability to delete chat

 def num(value: str, default: Optional[int] = None) -> Optional[int]:         return default  -def is_yes(resp: str) -> bool:-    if resp.strip().lower() == "y" or resp == "":+def is_yes(resp: Optional[str]) -> bool:+    if not resp or resp.strip().lower() == "y":+        return True+    return False+++def is_no(resp: Optional[str]) -> bool:

just return not resp or resp.strip().lower() == "n"

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Add ability to delete chat

 def num(value: str, default: Optional[int] = None) -> Optional[int]:         return default  -def is_yes(resp: str) -> bool:-    if resp.strip().lower() == "y" or resp == "":+def is_yes(resp: Optional[str]) -> bool:

it is not intuitive that is_yes(None) is True

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Add ability to delete chat

 def edit_msg(self) -> None:                     self.model.edit_message(text=text)                     self.present_info("Message edited") +    @bind(chat_handler, ["dd"])+    def leave_chat(self) -> None:+        """Leave group or cloase private, secret chat"""+        # can_be_deleted_only_for_self+        # can_be_deleted_for_all_users+        chat = self.model.chats.chats[self.model.current_chat]+        resp = self.view.status.get_input(+            "Are you sure you want to delete the chat?[y/N]"+        )+        if resp is None or is_no(resp):

resp is None is redundant

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Contacts search

 def reply_message(          return self._send_data(data) +    def search_contacts(self, target: str) -> AsyncResult:+        data = {"@type": "searchChats", "query": target, "limit": 10}

done

lightme16

comment created time in 2 months

push eventpaul-nameless/tg

Alexander Zveruk

commit sha b0034ef245f34e7e46038c20c4e310416f3d9f47

add optional param

view details

push time in 2 months

PR opened paul-nameless/tg

Contacts search
  • / searches chats by sending request to tdlib
  • n and N are used to cycle between founded chats
+74 -7

0 comment

4 changed files

pr created time in 2 months

push eventpaul-nameless/tg

Nameless

commit sha 111685170cc6b6f4afbe1fc1d9faa0e918c462e3

Fix disappearing msgs (#132)

view details

Nameless

commit sha f838f91bfe53c1dc16e40d01c4438c0c2c75b1c4

Expand user when getting file path (#133)

view details

Paul Nameless

commit sha 866a145a5623fca471ac05cbc3363fdf1eeec302

Release 0.4.0

view details

Nameless

commit sha d5e557beff5560c9a1490b57d154f71b714eb785

128: Update readme with correct configuration (#135)

view details

Nameless

commit sha 39a1e59f352bbb8e1b22104c2353f262e7be7f68

Use different storage model for msgs (#134) * Use different storage model for msgs * Do not sort if msg id already in right order

view details

Nameless

commit sha b37bba8fb76332ebe4f8ce7a1fb29955e2dab354

File picker (#136) * File picker * Add docstring to show in help * Update doc * Fix update_file: invalid get msg * Catch ValueError when removing messages * Ask to whether to upload file as document or compressed * Clear status after sending file

view details

Nameless

commit sha 4aaf9d9d1fe876ea58cff6fde2079fb67ceee0c9

update readme (#142) * Add contacts shortcut and link to config file * Remove logging in utils * Remove unused imports and create script for checking formatting * Remove unused import <Iterable> in models * Fix check.sh script * Reformat check.sh * Update isort * Add check flag for black

view details

Nameless

commit sha c020ba1ea7164751e0e7f83d90a61564a09a3d08

When entered markdown formatted text, parse it to display propely on official clients (#140)

view details

lightme16

commit sha 2a488341beba2a6e4f3bde95ffaba7db3e33bbae

wip

view details

Alexander Zveruk

commit sha 8dce217c908cb595dbcf16fd7cb400085ecaba8f

Merge branch 'master' into contacts-search

view details

Alexander Zveruk

commit sha c68905ee5cab17d1680ffe1b2a13a5354ceca073

improve search displaying

view details

Alexander Zveruk

commit sha 11dfae5d179de04c65186c085db9635cd096a4d8

add next chat support

view details

Alexander Zveruk

commit sha 98c0e161b66e7205f10b632755a3358d43535f2d

navigate chats backwards

view details

Alexander Zveruk

commit sha 9277e140d02317890f894779a536fd3a0e1d58e4

prettify

view details

push time in 2 months

push eventpaul-nameless/tg

Nameless

commit sha c020ba1ea7164751e0e7f83d90a61564a09a3d08

When entered markdown formatted text, parse it to display propely on official clients (#140)

view details

push time in 2 months

delete branch paul-nameless/tg

delete branch : text-formatting

delete time in 2 months

PR merged paul-nameless/tg

When entered markdown formatted text, parse it to display propely on official clients

Parse text formatting when sending #131

+40 -3

0 comment

2 changed files

paul-nameless

pr closed time in 2 months

push eventpaul-nameless/tg

Nameless

commit sha 4aaf9d9d1fe876ea58cff6fde2079fb67ceee0c9

update readme (#142) * Add contacts shortcut and link to config file * Remove logging in utils * Remove unused imports and create script for checking formatting * Remove unused import <Iterable> in models * Fix check.sh script * Reformat check.sh * Update isort * Add check flag for black

view details

push time in 2 months

delete branch paul-nameless/tg

delete branch : update-readme

delete time in 2 months

PR merged paul-nameless/tg

update readme
  • Add contacts shortcut and link to config file
  • Remove logging in utils
  • Remove unused imports and create script for checking formatting
  • Remove unused import <Iterable> in models
  • Fix check.sh script
  • Reformat check.sh
+44 -30

0 comment

8 changed files

paul-nameless

pr closed time in 2 months

create barnchpaul-nameless/tg

branch : contacts-search

created branch time in 2 months

Pull request review commentpaul-nameless/tg

File picker

 def render(self) -> None:         self.queue.put(self._render)      def _render(self) -> None:-        self.render_chats()-        self.render_msgs()+        self._render_chats()+        self._render_msgs()+        self._render_status()

that is incorrect. it creates unexpected behavior when sending msgs with i. each render invocation removes msg entered. so, status line shouldn't be updated during msg inserting.

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

File picker

 def delete_msgs(self) -> None:             return         self.present_info("Message deleted") +    @bind(msg_handler, ["S"])+    def choose_and_send_file(self) -> None:+        """Call file picker and send chosen file based on mimetype"""+        chat_id = self.model.chats.id_by_index(self.model.current_chat)+        file_path = None+        if not chat_id:+            return self.present_error("No chat selected")+        try:+            with NamedTemporaryFile("w") as f, suspend(self.view) as s:+                s.call(config.FILE_PICKER_CMD.format(file_path=f.name))+                with open(f.name) as f:+                    file_path = f.read().strip()+        except FileNotFoundError:+            pass+        if not file_path or not os.path.isfile(file_path):+            return self.present_error("No file was selected")+        mime_map = {+            "image": self.tg.send_photo,+            "audio": self.tg.send_audio,+            "video": self._send_video,+        }+        mime = get_mime(file_path)+        if mime in ("image", "video"):+            resp = self.view.status.get_input(

we need to clean up status line after prompting user.

paul-nameless

comment created time in 2 months

issue commentpaul-nameless/tg

Glitch in Insert mode

+1, having the same issue. We need to revisit code and fix it.

Yodzorah

comment created time in 2 months

Pull request review commentpaul-nameless/tg

File picker

 def send_picture(self) -> None:     def send_audio(self) -> None:         self.send_file(self.tg.send_audio) +    @bind(msg_handler, ["sv"])+    def send_video(self) -> None:

add doc string

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

File picker

 def delete_msgs(self) -> None:             return         self.present_info("Message deleted") +    @bind(msg_handler, ["S"])+    def choose_and_send_file(self) -> None:

plz add doc string so it will be displayed in help ?

paul-nameless

comment created time in 2 months

issue commentpaul-nameless/tg

Update msgs/chats list

I also noticed issue with msg editing. It is reproducing only for last msg in the chat for me. However, there are no problems with editing some older message. I think it is a recent but, because it used to work correctly.

Yodzorah

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Use different storage model for msgs

 def jump_bottom(self, chat_id: int) -> bool:      def prev_msg(self, chat_id: int, step: int = 1) -> bool:         new_idx = self.current_msgs[chat_id] + step-        if new_idx < len(self.msgs[chat_id]):+        if new_idx < len(self.msg_ids[chat_id]):             self.current_msgs[chat_id] = new_idx             return True         return False      def get_message(self, chat_id: int, msg_id: int) -> Optional[Dict]:         if msg_id in self.not_found:             return None-        if index := self.msg_idx[chat_id].get(msg_id):-            return self.msgs[chat_id][index]-        # we are not storing any out of ordres old msgs-        # just fetching them on demand+        if msg := self.msgs[chat_id].get(msg_id):+            return msg         result = self.tg.get_message(chat_id, msg_id)         result.wait()         if result.error:             self.not_found.add(msg_id)             return None         return result.update -    def remove_messages(self, chat_id: int, msg_idx: List[int]) -> None:-        log.info(f"removing msg {msg_idx=}")-        self.msgs[chat_id] = [-            m for m in self.msgs[chat_id] if m["id"] not in msg_idx-        ]-        self.msg_idx[chat_id] = {-            msg["id"]: i for i, msg in enumerate(self.msgs[chat_id])-        }+    def remove_messages(self, chat_id: int, msg_ids: List[int]) -> None:+        log.info(f"removing msg {msg_ids=}")+        for msg_id in msg_ids:+            self.msg_ids[chat_id].remove(msg_id)+            self.msgs[chat_id].pop(msg_id, None)      def add_message(self, chat_id: int, msg: Dict[str, Any]) -> None:         log.info(f"adding {msg=}")-        self.msgs[chat_id] = sorted(-            self.msgs[chat_id] + [msg], key=lambda d: d["id"], reverse=True,-        )-        self.msg_idx[chat_id] = {-            msg["id"]: i for i, msg in enumerate(self.msgs[chat_id])-        }+        msg_id = msg["id"]+        self.msgs[chat_id][msg_id] = msg+        self.msg_ids[chat_id].append(msg_id)+        self.msg_ids[chat_id].sort(reverse=True)

we can remove redundant sort operations with: if msg_id < self.msg_ids[chat_id][1]: self.msg_ids[chat_id].sort(reverse=True)

paul-nameless

comment created time in 2 months

pull request commentpaul-nameless/tg

Edit messages inside the interface

Hello, thanks for your PR. I like your idea, but have suggestion how to improve it. In this PR e does msg rewrite, instead of actual message edit. So, let's display old message in status panel and allow user to edit it without retyping. You can use this patch to achieve it:

diff --git a/tg/controllers.py b/tg/controllers.py
index 9cc481f..5decc80 100644
--- a/tg/controllers.py
+++ b/tg/controllers.py
@@ -442,7 +442,7 @@ class Controller:
         if not msg.can_be_edited:
             return self.present_error("Message can't be edited!")
 
-        if text := self.view.status.get_input():
+        if text := self.view.status.get_input(msg.text_content):
             self.model.edit_message(text=text)
             self.present_info("Message edited")
         else:
@@ -459,7 +459,6 @@ class Controller:
         if not msg.can_be_edited:
             return self.present_error("Message can't be edited!")
 
-
         with NamedTemporaryFile("r+", suffix=".txt") as f, suspend(
             self.view
         ) as s:
diff --git a/tg/views.py b/tg/views.py
index da50386..b457df1 100644
--- a/tg/views.py
+++ b/tg/views.py
@@ -105,14 +105,18 @@ class StatusView:
         self.win.addstr(0, 0, msg.replace("\n", " ")[: self.w])
         self._refresh()
 
-    def get_input(self, msg: str = "") -> str:
-        self.draw(msg)
+    def get_input(self, buff: str = "") -> str:
+        self.draw(buff)
         curses.curs_set(1)
 
-        buff = ""
         while True:
-            key = self.win.get_wch(0, min(len(buff) + len(msg), self.w - 1))
+            self.win.erase()
+            line = buff[-(self.w - 1) :]
+            self.win.addstr(0, 0, line)
+
+            key = self.win.get_wch(0, min(len(buff), self.w - 1))
             key = ord(key)
+
             if key == 10:  # return
                 break
             elif key == 127:  # del
@@ -123,9 +127,6 @@ class StatusView:
                 break
             elif chr(key).isprintable():
                 buff += chr(key)
-            self.win.erase()
-            line = (msg + buff)[-(self.w - 1) :]
-            self.win.addstr(0, 0, line)
 
         self.win.clear()
         curses.curs_set(0)

Also, plz pay attention to the CI checks, they are red now. You can find CI command here https://github.com/paul-nameless/tg/blob/master/.github/workflows/main.yml#L39-L47

ArthurBais

comment created time in 2 months

push eventpaul-nameless/tg

Nameless

commit sha aeab7c15643c188731e9984e407a5966e8c65e9e

Add <secret> chat flag (#121)

view details

push time in 2 months

delete branch paul-nameless/tg

delete branch : secret

delete time in 2 months

PR merged paul-nameless/tg

Add <secret> chat flag
+4 -0

0 comment

2 changed files

paul-nameless

pr closed time in 2 months

push eventpaul-nameless/tg

lightme16

commit sha 2e9c3ff8564c631adceae2a71fad06d00747e14e

fix mypy issue

view details

push time in 2 months

push eventpaul-nameless/tg

lightme16

commit sha 3386416a1a1dac64c794d56b613c38fc92881363

respond to comments

view details

push time in 2 months

Pull request review commentpaul-nameless/tg

Update new chat

 def fetch_chat(self, chat_id: int) -> Dict[str, Any]:             return {}         return result.update +    def add_chat(self, chat: Dict[str, Any]) -> None:+        chat_id = int(chat["id"])

right

lightme16

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Update new chat

 def fetch_chat(self, chat_id: int) -> Dict[str, Any]:             return {}         return result.update +    def add_chat(self, chat: Dict[str, Any]) -> None:+        chat_id = int(chat["id"])+        if chat_id in self.chat_ids:+            return+        if int(chat["order"]) == 0:+            self.inactive_chats[chat["id"]] = chat

done

lightme16

comment created time in 2 months

push eventpaul-nameless/tg

lightme16

commit sha 8de913a4843a98a765223ebba0469ff715cf49e3

respond to comments

view details

lightme16

commit sha c4a01578a3f8fe043e811c2ae7394a96cf69f529

support chat removal

view details

push time in 2 months

Pull request review commentpaul-nameless/tg

Show list of contacts

 def edit_msg(self) -> None:                     self.model.edit_message(text=text)                     self.present_info("Message edited") +    @bind(chat_handler, ["c"])+    def view_contacts(self) -> None:+        contacts = self.model.users.get_contacts()+        if not contacts:+            return self.present_error("Can't get contacts")++        total = contacts["total_count"]+        users = [f"{total} users:"]+        for user_id in contacts["user_ids"]:+            user = get_user_label(self.model.users, user_id)

I see. In the official client they showing contacts in the status bar, so they are limited in space. But we are having full text page available for the contacts, so adding number would be nice. Because this feature is useless for end user now. Of course, we can add it now, but it defenetly requires some more work. Also, I would like to have chat ordered by last online data like telegram web does.

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Use the __main__.py special filename for main.py

 From sources: pip3 install python-telegram git clone git@github.com:paul-nameless/tg.git cd tg-PYTHONPATH=. python3 tg/main.py+PYTHONPATH=. +python3 tg/main.py

so, need command should be python -m tg, isn't it? then PYTHONPATH could be omitted.

Steffo99

comment created time in 2 months

push eventpaul-nameless/tg

lightme16

commit sha 80a8d79b8eb909a943634669a7266ee891193452

use add_chat

view details

push time in 2 months

push eventpaul-nameless/tg

Nameless

commit sha eabe39d3c469ba3cb4f7f9b288728675c088beae

Add indexes for msgs (#91) * Draft: adding lock to message update and using indexes for msgs * Fix black formatting * Rename msg_ids->msg_idx to better represent what variable contains * Fix black formatting * Check if msg_id in not_found * Use lock in udpate_handler * Remove lock

view details

Nameless

commit sha 2a0c7267926be0b6ffe455906b136804eaf8c612

jump to reply (#105) * Draft: adding lock to message update and using indexes for msgs * Fix black formatting * Rename msg_ids->msg_idx to better represent what variable contains * Fix black formatting * Check if msg_id in not_found * Use lock in udpate_handler * Add shortcut to jump to replied msg * Show correct error msg when trying to jump to reply msg which does not replies * Remove lock

view details

Nameless

commit sha 4460c5f94b91906313e8637f8e1281785e6d3e79

View animated stickers thumbnail (#106) * Draft: adding lock to message update and using indexes for msgs * Fix black formatting * Rename msg_ids->msg_idx to better represent what variable contains * Fix black formatting * Check if msg_id in not_found * Use lock in udpate_handler * Add shortcut to jump to replied msg * Open preview for animated sticker and show it's emoji * Remove lock * Show if sticker is animated

view details

Alex

commit sha 5b660f47eb07b8532b9c9dc72afe3bd619a13c7d

Show last msg sender user name in group chat preview (#104) * wip * preview last msgs sender for group chats * user name for actions * refactor * another refactor * remove :

view details

lightme16

commit sha 3b7a8451f5a56bb1c839b93d47ef155e2df586f3

workaround

view details

Nameless

commit sha 9224de41100baf800f2e4021d5c168f7ce9e7d8e

Select msg and go to previous one with ctrl+space (#108)

view details

Nameless

commit sha 5b53495b6031e3d7fa08da698896382631da7fd3

Display shorter date in chats (#109)

view details

lightme16

commit sha 94628bb5b5ce0f1eb2264a840ff273a1a98579a4

Merge branch 'master' into updateNewChat

view details

Paul Nameless

commit sha fcfa89902a48fa230624bdcec6ca8991297bf9ef

Allow to open current msg with custom cmd

view details

Paul Nameless

commit sha 54fb4e9f0087faf7e484b084eb64532af649f703

Implement messageBasicGroupChatCreate and messageBasicGroupChatCreate msg types

view details

Paul Nameless

commit sha af7f1ee2026a7dd4d37841fdc331415bcf185fdd

Update README key bindings

view details

Nameless

commit sha af47b1e7c89a4dd17b37ccf3a9727868507f9d4a

Merge pull request #112 from paul-nameless/implement-msg-types Implement messageBasicGroupChatCreate and messageBasicGroupChatCreate msg types

view details

Paul Nameless

commit sha 453cdbcc45022d2de9090068d0c0427a1a642c76

Improve logging (add filename) and add help string for open_current_msg

view details

Nameless

commit sha 73d3e535bbe0e396824b26547041d80d43a57720

Merge pull request #111 from paul-nameless/custom-cmd Allow to open current msg with custom cmd

view details

Nameless

commit sha a053fdefecb3fc8b3cbb0597e5f02ee3e959f3a0

Update README with sticker info, telegram chat and key bindings (#113) * Update README with sticker info, telegram chat and key bindings * Update screenshot * Rename README.md -> readme.md

view details

Nameless

commit sha 568e15aecbe74e97a3fdbadb475192185c4448fd

Check if msg index exists firstly: causes KeyError in logs (#114)

view details

lightme16

commit sha 8a44f60ebf9c5859b3ae61d66cffc8a3bc5c59f5

Improve user typing label

view details

Nameless

commit sha c567e3c599ceeebb591e13a94d80e60cee244091

Do not pipe stderr, cause it hides ffmpeg output (#115) * Do not pipe stderr, cause it hides ffmpeg output * Improve cmd failed message

view details

Alex

commit sha 7ceb4dcd9c6cf459f51d705eda12bd7412d94882

View polls (#110) * poc * refactor * fix isort * respond to comments * use "closed" woring

view details

Nameless

commit sha 7b03096bd0d8a8674514948ce87ab4f789117094

Merge pull request #117 from paul-nameless/improve-user-typing-label Improve user typing label

view details

push time in 2 months

pull request commentpaul-nameless/tg

Use the __main__.py special filename for main.py

@Steffo99 Hello, thanks for PR. To be consistent you may want to update https://github.com/paul-nameless/tg/blob/master/pyproject.toml#L16 and README as well. But, why don't you like to use python tg/main.py cmd? I can't see any problems with current approach right now, so this PR doesn't look like noticeable improvement.

Steffo99

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show list of contacts

 def edit_msg(self) -> None:                     self.model.edit_message(text=text)                     self.present_info("Message edited") +    @bind(chat_handler, ["c"])+    def view_contacts(self) -> None:+        contacts = self.model.users.get_contacts()+        if not contacts:+            return self.present_error("Can't get contacts")++        total = contacts["total_count"]+        users = [f"{total} users:"]+        for user_id in contacts["user_ids"]:+            user = get_user_label(self.model.users, user_id)

get_user_label it is of for POC, but to make this useful it would be nice to display phone number as well.

paul-nameless

comment created time in 2 months

Pull request review commentpaul-nameless/tg

Show list of contacts

 def edit_msg(self) -> None:                     self.model.edit_message(text=text)                     self.present_info("Message edited") +    @bind(chat_handler, ["c"])+    def view_contacts(self) -> None:+        contacts = self.model.users.get_contacts()+        if not contacts:+            return self.present_error("Can't get contacts")++        total = contacts["total_count"]+        users = [f"{total} users:"]+        for user_id in contacts["user_ids"]:+            user = get_user_label(self.model.users, user_id)+            status = self.model.users.get_status(user_id)+            users.append(f"{user:<40} | {status}")

40 chars could be redundant and wasteful screen use. we can use min(40, len(longest_contant_name))

paul-nameless

comment created time in 2 months

PR opened paul-nameless/tg

Improve user typing label
  • print "user typing" instead o "user is typing"
  • don't print "user typing" for DM
+12 -6

0 comment

1 changed file

pr created time in 2 months

create barnchpaul-nameless/tg

branch : improve-user-typing-label

created branch time in 2 months

more