profile
viewpoint

paul-nameless/tg 118

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.

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 17 hours

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 17 hours

push eventpaul-nameless/tg

lightme16

commit sha 80a8d79b8eb909a943634669a7266ee891193452

use add_chat

view details

push time in a day

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 a day

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 a day

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 a day

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 a day

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 3 days

create barnchpaul-nameless/tg

branch : improve-user-typing-label

created branch time in 3 days

Pull request review commentpaul-nameless/tg

Do not pipe stderr, cause it hides ffmpeg output

 def __init__(self, view: Any) -> None:         self.view = view      def call(self, cmd: str) -> CompletedProcess:-        return subprocess.run(cmd, shell=True, stderr=subprocess.PIPE)+        return subprocess.run(cmd, shell=True)      def run_with_input(self, cmd: str, text: str) -> None:         subprocess.run(cmd, universal_newlines=True, input=text, shell=True) -    def open_file(self, file_path: str, cmd: str = None) -> str:+    def open_file(self, file_path: str, cmd: str = None) -> None:         if cmd:-            try:-                cmd = cmd % shlex.quote(file_path)-            except TypeError:-                return "command should contain <%s> which will be replaced by file path"+            cmd = cmd % shlex.quote(file_path)         else:             cmd = get_file_handler(file_path)          proc = self.call(cmd)         if proc.returncode:-            stderr = proc.stderr.decode()-            log.error("Error happened executing <%s>:\n%s", cmd, stderr)-            return stderr-        return ""+            input("Cmd failed: press <enter> to continue")

plz, use cmd instead of Cmd. I believe we are using lower cases everywhere

paul-nameless

comment created time in 3 days

push eventpaul-nameless/tg

Nameless

commit sha 568e15aecbe74e97a3fdbadb475192185c4448fd

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

view details

push time in 3 days

delete branch paul-nameless/tg

delete branch : fix-key-error

delete time in 3 days

push eventpaul-nameless/tg

Alex

commit sha 2150cec8828cbc139d41741a239403d4d9bb2a7e

use "closed" woring

view details

push time in 3 days

push eventpaul-nameless/tg

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

lightme16

commit sha 36c9bc3d0def8ca3050faea74156ef2ce6ff6aa1

respond to comments

view details

lightme16

commit sha c03b3e4deda423426a2a30fcb55c8e530346c63f

Merge branch 'master' into view-polls

view details

push time in 4 days

Pull request review commentpaul-nameless/tg

Allow to open current msg with custom cmd

 def draw(self, msg: Optional[str] = None) -> None:         self.win.clear()         if not msg:             return-        self.win.addstr(0, 0, msg[: self.w])+        self.win.addstr(0, 0, msg.replace("\n", " ")[: self.w])

oh, it is StatusView. ok then

paul-nameless

comment created time in 4 days

Pull request review commentpaul-nameless/tg

Allow to open current msg with custom cmd

 def draw(self, msg: Optional[str] = None) -> None:         self.win.clear()         if not msg:             return-        self.win.addstr(0, 0, msg[: self.w])+        self.win.addstr(0, 0, msg.replace("\n", " ")[: self.w])

I think we shouldn't do any msg transformation here, just print it as it here e.g here https://github.com/paul-nameless/tg/pull/110/files#diff-dd82b960530ded14e2504f2515ced08fR565 all message transformation should be done in functions like parse_content, etc

paul-nameless

comment created time in 4 days

Pull request review commentpaul-nameless/tg

Allow to open current msg with custom cmd

 def open_current_msg(self) -> None:             return         self.tg.open_message_content(chat_id, msg.msg_id)         with suspend(self.view) as s:-            s.open_file(path)+            if err_msg := s.open_file(path, cmd):+                self.present_error(err_msg)++    @bind(msg_handler, ["!"])+    def open_msg_with_cmd(self) -> None:+        """Open msg or file with cmd: less %s"""+        msg = MsgProxy(self.model.current_msg)+        if cmd := self.view.status.get_input():+            return self._open_msg(msg, cmd)++    @bind(msg_handler, ["l", "^J"])+    def open_current_msg(self) -> None:

plz add doc string for help msg generation

paul-nameless

comment created time in 4 days

push eventpaul-nameless/tg

lightme16

commit sha f133bbe84d3c1001addb482cc63582762434e12c

fix isort

view details

push time in 4 days

push eventpaul-nameless/tg

lightme16

commit sha cfc839c99406b09ab1ae8259a463bc4b0f10a80a

refactor

view details

push time in 4 days

PR opened paul-nameless/tg

View polls
  • preview poll.
  • poll actions(e.g votes) will be added later
+29 -5

0 comment

2 changed files

pr created time in 4 days

create barnchpaul-nameless/tg

branch : view-polls

created branch time in 4 days

delete branch paul-nameless/tg

delete branch : shorted-chat-date

delete time in 4 days

push eventpaul-nameless/tg

Nameless

commit sha 5b53495b6031e3d7fa08da698896382631da7fd3

Display shorter date in chats (#109)

view details

push time in 4 days

PR merged paul-nameless/tg

Display shorter date in chats

There is no need to display current year in chat date. If it is previous year, then display it.

+6 -3

0 comment

1 changed file

paul-nameless

pr closed time in 4 days

push eventpaul-nameless/tg

Nameless

commit sha 9224de41100baf800f2e4021d5c168f7ce9e7d8e

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

view details

push time in 4 days

delete branch paul-nameless/tg

delete branch : toggle-up

delete time in 4 days

startedtpierrain/CQRS

started time in 5 days

push eventpaul-nameless/tg

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

push time in 5 days

delete branch paul-nameless/tg

delete branch : user-name-in-group-chat-preview

delete time in 5 days

PR merged paul-nameless/tg

Reviewers
Show last msg sender user name in group chat preview ready for merge
  • show user name in chat preview
  • show user name for action label (tom is typing...)
+92 -64

1 comment

3 changed files

lightme16

pr closed time in 5 days

push eventpaul-nameless/tg

Alexander Zveruk

commit sha 9a85ac584cc472a0c8624c0b595daab36d6a03cf

wip

view details

Alexander Zveruk

commit sha 5f5b3e96459d5867765fda6f15ded258aafa3bdb

preview last msgs sender for group chats

view details

Alexander Zveruk

commit sha 60b6ae4dd27b4a410523af0a92c4fd9240cc0c79

user name for actions

view details

Alexander Zveruk

commit sha b406cc9e6d4eaeb081ff167a48660f06068e9c28

refactor

view details

Alexander Zveruk

commit sha d4be7fb138596d2eeca1b20a01bf541bf049cfa2

another refactor

view details

Alexander Zveruk

commit sha 9f7ce7678a57c6802198744f60feb1de7260f912

remove :

view details

lightme16

commit sha d83c2d24eec626f6728571b4ce4f3cd19590f49a

Merge branch 'user-name-in-group-chat-preview' of github.com:paul-nameless/tg into user-name-in-group-chat-preview

view details

push time in 5 days

PR opened paul-nameless/tg

Reviewers
Update new chat
  • process updateNewChat update to add new change when it is created from another telegram client
+38 -16

0 comment

2 changed files

pr created time in 5 days

push eventpaul-nameless/tg

Alexander Zveruk

commit sha 0526cea7e6a49ce408c3c84033dfdcbff907af79

Merge branch 'master' into updateNewChat

view details

push time in 5 days

create barnchpaul-nameless/tg

branch : updateNewChat

created branch time in 5 days

push eventpaul-nameless/tg

Nameless

commit sha 723bd5cfeb248759e914916c1213de3784c95a7b

Cleanup cache: delete files older than days specified in config (#103) * Cleanup cache: delete files older than days specified in config * Use subprocess.Popen instead of os.system (does not wait for completion) * Do not print infor about cleanup to stdout

view details

Alexander Zveruk

commit sha a901a80c6f83c5a0b5f932c66a19e34681b1f0b5

user name for actions

view details

Alexander Zveruk

commit sha f77757ead77ad44c28fde324a69c840d216bd734

refactor

view details

Alexander Zveruk

commit sha 6c56d22e10e94ebfe8bfdcbe55cb94bf23135523

another refactor

view details

Alexander Zveruk

commit sha f70b98890103a834fad20543843b9ac2ab5fb71f

Merge branch 'master' into user-name-in-group-chat-preview

view details

Alexander Zveruk

commit sha 91195b5ef4831b9a2989dfda88248366ef79f12f

remove :

view details

push time in 5 days

Pull request review commentpaul-nameless/tg

Adding lock to message update and using indexes for msgs

 def decorator(fun: UpdateHandler) -> UpdateHandler:         @wraps(fun)         def wrapper(controller: Controller, update: Dict[str, Any]) -> None:             try:-                fun(controller, update)+                with controller.lock:+                    fun(controller, update)

btw, missing 2 change in one PR is not the best idea. lock vs idxs

paul-nameless

comment created time in 5 days

Pull request review commentpaul-nameless/tg

Adding lock to message update and using indexes for msgs

 def decorator(fun: UpdateHandler) -> UpdateHandler:         @wraps(fun)         def wrapper(controller: Controller, update: Dict[str, Any]) -> None:             try:-                fun(controller, update)+                with controller.lock:+                    fun(controller, update)

Why do we need this lock? I think it is redundant. All update are processed in sync, one event in the time, this code run in separate thread.

paul-nameless

comment created time in 5 days

pull request commentpaul-nameless/tg

View animated stickers thumbnail

plz stop creatingss PR into non master branches. there is no need to create nested PRs. I want to merge this PR, but can't due to nested dependencies.

paul-nameless

comment created time in 5 days

pull request commentpaul-nameless/tg

jump to reply

plz stop create PR into master. there is no need to created nested PRs

paul-nameless

comment created time in 5 days

push eventpaul-nameless/tg

Nameless

commit sha 723bd5cfeb248759e914916c1213de3784c95a7b

Cleanup cache: delete files older than days specified in config (#103) * Cleanup cache: delete files older than days specified in config * Use subprocess.Popen instead of os.system (does not wait for completion) * Do not print infor about cleanup to stdout

view details

push time in 5 days

delete branch paul-nameless/tg

delete branch : cleanup-cache

delete time in 5 days

Pull request review commentpaul-nameless/tg

jump to reply

 def quit(self) -> str:     def back(self) -> str:         return "BACK" +    @bind(msg_handler, ["m"])+    def jump_to_reply_msg(self) -> None:+        chat_id = self.model.chats.id_by_index(self.model.current_chat)+        if not chat_id:+            return+        msg = MsgProxy(self.model.current_msg)+        if msg_id := msg.reply_msg_id:+            if self.model.msgs.jump_to_msg_by_id(chat_id, msg_id):+                return self.render_msgs()+        self.present_error("Can't jump to reply msg: it's not preloaded")

misleading error text. If i press m for message without reply in it I expect different error.

paul-nameless

comment created time in 5 days

create barnchpaul-nameless/tg

branch : user-name-in-group-chat-preview

created branch time in 6 days

Pull request review commentpaul-nameless/tg

Cleanup cache: delete files older than days specified in config

 def get_color_by_str(user: str) -> int:         config.USERS_COLORS     )     return config.USERS_COLORS[index]+++def cleanup_cache() -> None:+    if not config.KEEP_MEDIA:+        print("Skipping cleaning cache...")+        return+    files_path = os.path.join(config.FILES_DIR, "files")+    print(

why you aren't using logger here? this will be printed to foreground:

Cleaning up cache files older than 7 days at: /home/user/.cache/tg/files
paul-nameless

comment created time in 6 days

startedTelegram-FOSS-Team/Telegram-FOSS

started time in 6 days

Pull request review commentpaul-nameless/tg

Fix bug in update handler decorator

 def decorator(fun: UpdateHandler) -> UpdateHandler:             update_type not in handlers         ), f"Update type <{update_type}> already has handler: {handlers[update_type]}" -        handlers[update_type] = fun-         @wraps(fun)         def wrapper(controller: Controller, update: Dict[str, Any]) -> None:             try:-                return fun(controller, update)+                fun(controller, update)             except Exception:-                log.exception("Error happened in %s handler", fun.__name__)+                log.exception("Error happened in handler: %s", update_type) +        handlers[update_type] = wrapper

🎉

paul-nameless

comment created time in 6 days

Pull request review commentpaul-nameless/tg

Fix bug in update handler decorator

 def remove_messages(self, chat_id: int, msg_ids: List[int]) -> None:         ]         msg_set = self.msg_ids[chat_id]         for msg_id in msg_ids:-            msg_set.remove(msg_id)+            try:+                msg_set.remove(msg_id)

just msg_set.discard(msg_id)

paul-nameless

comment created time in 6 days

Pull request review commentpaul-nameless/tg

Draw users with different colors

 def _unread_color(self, is_selected: bool = False) -> int:             return color | reverse         return color -    def _chat_attributes(self, is_selected: bool = False) -> Tuple[int, ...]:+    def _chat_attributes(+        self, is_selected: bool, title: str+    ) -> Tuple[int, ...]:         attrs = (             get_color(cyan, -1),+            get_color(get_color_by_user(title), -1),

this function should be renamed to more generic name e.g get_color_by_text | get_color_from_str

paul-nameless

comment created time in 7 days

Pull request review commentpaul-nameless/tg

Draw users with different colors

 MSG_FLAGS = {  # use this app to open url when there are multiple URL_VIEW = 'urlview'++# Specifies range of colors to use for drawing different users+# - 1, 8, 16, 256: range of colors to use+# 233 is recommended and default, because it excludes gray+USERS_COLORS = tuple(range(233))

let's use 16 colors by default. because it looks good both for light & dark terminal. 233 looks bad on light theme

paul-nameless

comment created time in 7 days

Pull request review commentpaul-nameless/tg

Draw users with different colors

 yellow = curses.COLOR_YELLOW default = -1 ++user_colors = list(c for c in range(0, 16) if c not in (black, white, 8))

where is it used?

paul-nameless

comment created time in 7 days

Pull request review commentpaul-nameless/tg

Draw users with different colors

  URL_VIEW = "urlview" +USERS_COLORS = 234

why does it differs from value in README?

paul-nameless

comment created time in 7 days

issue commentpaul-nameless/tg

Emoji "picker"

Thanks, we also thought about emoji pickier however didn't implement it in the first version, because it seems to be not essential for the app. Maybe we can add this later. Also, strictly speaking, picking emoji it is a generic capability and it isn't the responsibility of the telegram client. You can have an external tool that helps you to paste emojis into the various application to follow Unix coventions about software modularity. Here is example of this idea for Linux and dmenu.

jugendhacker

comment created time in 7 days

push eventpaul-nameless/tg

Nameless

commit sha 3ceb8169616f1ffa1a80ea1afc98d3a6fb641c3a

remove msgs (#98) * Delete msgs in batch

view details

push time in 7 days

delete branch paul-nameless/tg

delete branch : remove-msgs

delete time in 7 days

PR merged paul-nameless/tg

Reviewers
remove msgs
  • Delete msgs in batch
+17 -11

0 comment

4 changed files

paul-nameless

pr closed time in 7 days

delete branch paul-nameless/tg

delete branch : msg-not-found

delete time in 7 days

push eventpaul-nameless/tg

Nameless

commit sha d560eee3b74825f5cda2b53680cef7d7035d8a23

Check msg not-found cache (#99) * Check msg not-found cache * Fix syntax error

view details

push time in 7 days

PR merged paul-nameless/tg

Check msg not-found cache
+2 -0

0 comment

1 changed file

paul-nameless

pr closed time in 7 days

delete branch paul-nameless/tg

delete branch : caption

delete time in 7 days

push eventpaul-nameless/tg

Nameless

commit sha 7ec5742a17efac9fd2a795d567bb4308f0210e82

Display caption (when doc sent with text) (#97)

view details

push time in 7 days

issue commentpaul-nameless/tg

View glitch

Me also having similar problems with this border. However, for me, I believe the root cause it usage of the emojis for chat labels. image We will improve this code to make it more robust for different configurations.

For your case, do you have any emojis in the chat name? Or in the message in the same row?

jugendhacker

comment created time in 8 days

issue closedpaul-nameless/tg

Voice recording buggy

First of all thanks a lot for this awesome application!

Unfortunately I have some troubles with the voice recording. Not sure if I ever will use it :D but thought you might be interested.

This was my first bug: ALSA lib pcm_hw.c:1829:(_snd_pcm_hw_open) Invalid value for card [alsa @ 0x5626bffac2c0] cannot open audio device default (No such device) default: Input/output error

Fixed with adding that line to my conf.py VOICE_RECORD_CMD = "ffmpeg -f alsa -i hw:0 -c:a libopus -b:a 32k {file_path}"

But there is still another one:

Guessed Channel Layout for Input Stream #0.0 : stereo Input #0, alsa, from 'hw:0': Duration: N/A, start: 1592929738.453123, bitrate: 1536 kb/s Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s [NULL @ 0x558585020e00] Unable to find a suitable output format for '/tmp/voice-2020-06-23' /tmp/voice-2020-06-23: Invalid argument

closed time in 8 days

IvoLeist

issue commentpaul-nameless/tg

Voice recording buggy

@IvoLeist Cool! I updated default ffmpeg command for Linux here https://github.com/paul-nameless/tg/pull/95. Thanks for your report!

IvoLeist

comment created time in 8 days

PR opened paul-nameless/tg

Change default ffmpeg cmd for Linux

Change default ffmpeg cmd for Linux per request in the https://github.com/paul-nameless/tg/issues/86

+2 -1

0 comment

1 changed file

pr created time in 8 days

push eventpaul-nameless/tg

Alexander Zveruk

commit sha 22e7ba18a67d90549c5472687998a1a9e90568bd

Change default ffmpeg cmd for Linux

view details

push time in 8 days

create barnchpaul-nameless/tg

branch : change-ffmpeg-cmd-linux

created branch time in 8 days

Pull request review commentpaul-nameless/tg

Introduce top status panel

 def update_connection_state(controller: Controller, update: Dict[str, Any]):         "connectionStateConnectingToProxy": "Connecting to proxy...",         "connectionStateConnecting": "Connecting...",         "connectionStateUpdating": "Updating...",-        "connectionStateReady": "Ready",+        # "connectionStateReady": "Ready",     }-    msg = states.get(state, "Unknown state")-    controller.present_info(msg)+    controller.model.chats.title = states.get(state, "Chats")+    controller.render_chats()   @update_handler("updateUserStatus") def update_user_status(controller: Controller, update: Dict[str, Any]):     controller.model.users.set_status(update["user_id"], update["status"])-    controller.render_chats()+    controller.render()+++@update_handler("updateBasicGroup")+def update_basic_group(controller: Controller, update: Dict[str, Any]):+    basic_group = update["basic_group"]+    controller.model.users.groups[basic_group["id"]] = basic_group+    controller.render_msgs()+++@update_handler("updateSupergroup")+def update_supergroup(controller: Controller, update: Dict[str, Any]):+    supergroup = update["supergroup"]+    controller.model.users.supergroups[supergroup["id"]] = supergroup+    controller.render_msgs()+++@update_handler("updateUserChatAction")+def update_user_chat_action(controller: Controller, update: Dict[str, Any]):+    log.info("typing:: %s", update)

redundant log

paul-nameless

comment created time in 8 days

Pull request review commentpaul-nameless/tg

Introduce top status panel

 def update_connection_state(controller: Controller, update: Dict[str, Any]):         "connectionStateConnectingToProxy": "Connecting to proxy...",         "connectionStateConnecting": "Connecting...",         "connectionStateUpdating": "Updating...",-        "connectionStateReady": "Ready",+        # "connectionStateReady": "Ready",

why is it commented out? maybe remove?

paul-nameless

comment created time in 8 days

Pull request review commentpaul-nameless/tg

Introduce top status panel

 def get_user(self, user_id: int) -> Dict[str, Any]:             return {}         self.users[user_id] = result.update         return result.update++    def get_group_info(self, group_id):

add type annotation

paul-nameless

comment created time in 8 days

Pull request review commentpaul-nameless/tg

Introduce top status panel

 def __exit__(self, exc_type, exc_val, tb):  def set_shorter_esc_delay(delay=25):     os.environ.setdefault("ESCDELAY", str(delay))+++def pretty_ts(ts):

plz add type annotation

paul-nameless

comment created time in 8 days

Pull request review commentpaul-nameless/tg

More strict mypy checks

 def _refresh_current_chat(self, current_chat_id: Optional[int]):   def insert_replied_msg(msg: MsgProxy) -> str:-    text = msg.text_content if msg.is_text else msg.content_type-    return (-        "\n".join([f"{REPLY_MSG_PREFIX} {line}" for line in text.split("\n")])-        # adding line with whitespace so text editor could start editing from last line-        + "\n "-    )+    if text := msg.text_content if msg.is_text else msg.content_type:+        return (+            "\n".join(+                [f"{REPLY_MSG_PREFIX} {line}" for line in text.split("\n")]+            )+            # adding line with whitespace so text editor could start editing from last line+            + "\n "+        )+    else:

usually people avoid else to reduce nesting, so it could bee the only benefit here. readability is the same for both approaches.

lightme16

comment created time in 10 days

Pull request review commentpaul-nameless/tg

More strict mypy checks

 def _refresh_current_chat(self, current_chat_id: Optional[int]):   def insert_replied_msg(msg: MsgProxy) -> str:-    text = msg.text_content if msg.is_text else msg.content_type-    return (-        "\n".join([f"{REPLY_MSG_PREFIX} {line}" for line in text.split("\n")])-        # adding line with whitespace so text editor could start editing from last line-        + "\n "-    )+    if text := msg.text_content if msg.is_text else msg.content_type:+        return (+            "\n".join(+                [f"{REPLY_MSG_PREFIX} {line}" for line in text.split("\n")]+            )+            # adding line with whitespace so text editor could start editing from last line+            + "\n "+        )+    else:

I think you understand benefits from early returns and avoiding "else" and there is no need to explain them.

no, i can't see any befits for this particular case, so you can explain it a bit more 🙂 .

however, both approaches looks similar to me, so I removed else here

lightme16

comment created time in 10 days

push eventpaul-nameless/tg

Alexander Zveruk

commit sha 4a3ebe5b5d6f2be7f9de8ad74b0d9ad378678717

do not use else in insert_replied_msg

view details

push time in 10 days

push eventpaul-nameless/tg

Alexander Zveruk

commit sha 19dc0f4c9a2de223c7ed13deb19c04f01905c781

fix isort

view details

push time in 10 days

push eventpaul-nameless/tg

Alexander Zveruk

commit sha b4d373aee501af0a4a08c5854a43be5e2f7c3176

fix gly type signature

view details

push time in 10 days

PR opened paul-nameless/tg

More strict mypy checks
+277 -219

0 comment

10 changed files

pr created time in 10 days

push eventpaul-nameless/tg

Alexander Zveruk

commit sha 346c73d0c21de9bf23e0958c72ff3a8407c5ce94

update gitignore

view details

push time in 10 days

create barnchpaul-nameless/tg

branch : more-mypy-checks

created branch time in 10 days

Pull request review commentpaul-nameless/tg

Draft: introduce top status panel

 def get_user(self, user_id: int) -> Dict[str, Any]:             return {}         self.users[user_id] = result.update         return result.update++    def get_group_info(self, group_id):+        if group_id in self.groups:+            return self.groups[group_id]+        self.tg.get_basic_group(group_id)++    def get_supergroup_info(self, supergroup_id):+        if supergroup_id in self.supergroups:+            return self.supergroups[supergroup_id]+        self.tg.get_supergroup(supergroup_id)+++def pretty_ts(ts):+    from datetime import datetime

why local import? also, this function should be moved to some better place, maybe in the utils module

paul-nameless

comment created time in 10 days

Pull request review commentpaul-nameless/tg

Draft: introduce top status panel

+from enum import Enum from typing import Any, Dict, List  from telegram.client import AsyncResult, Telegram  +class Action(Enum):+    chatActionTyping = "typing"+    chatActionCancel = "cancel"+    chatActionRecordingVideo = "recording video"+    chatActionUploadingVideo = "uploading video"+    chatActionRecordingVoiceNote = "recording voice note"+    chatActionUploadingVoiceNote = "uploading voice note"

it is too verbose labels. telegram desktop shows only recording voice, so 3rd word note could be omitted.
image

paul-nameless

comment created time in 10 days

startedInstagram/MonkeyType

started time in 11 days

Pull request review commentpaul-nameless/tg

Draft: adding lock to message update and using indexes for msgs

 def prev_msg(self, chat_id: int, step: int = 1) -> bool:         if new_idx < len(self.msgs[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]:-        msg_set = self.msg_ids[chat_id]-        if msg_id not in msg_set:-            # we are not storing any out of ordres old msgs-            # just fetching then on demand-            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-        return next(iter(m for m in self.msgs[chat_id] if m["id"] == msg_id))--    def remove_message(self, chat_id: int, msg_id: int):-        msg_set = self.msg_ids[chat_id]-        if msg_id not in msg_set:-            return False-        log.info(f"removing msg {msg_id=}")-        # FIXME: potential bottleneck, replace with constan time operation-        self.msgs[chat_id] = [-            m for m in self.msgs[chat_id] if m["id"] != msg_id-        ]-        msg_set.remove(msg_id)-        return True+        with self.lock:+            index = self.msg_ids[chat_id].get(msg_id)+            if index:+                return self.msgs[chat_id][index]+        # we are not storing any out of ordres old msgs+        # just fetching them on demand+        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_ids: List[int]):+        with self.lock:+            log.info(f"removing msg {msg_ids=}")+            self.msgs[chat_id] = [+                m for m in self.msgs[chat_id] if m["id"] not in msg_ids+            ]+            self.msg_ids[chat_id] = {+                msg["id"]: i for i, msg in enumerate(self.msgs[chat_id])+            }++    def add_message(self, chat_id: int, msg: Dict[str, Any]):+        with self.lock:+            log.info(f"adding {msg=}")+            self.msgs[chat_id].append(msg)+            self.msgs[chat_id] = sorted(

also updating msg_ids could be simpler when msg['id'] > self.msgs[chat_id][-1]['id'] == True and it is a latest message. then you can do:

            self.msg_ids[chat_id][msg['id']] = self.msg_ids[chat_id][-1] + 1
paul-nameless

comment created time in 12 days

Pull request review commentpaul-nameless/tg

Draft: adding lock to message update and using indexes for msgs

 def __init__(self, tg: Tdlib):         self.msgs: Dict[int, List[Dict]] = defaultdict(list)         self.current_msgs: Dict[int, int] = defaultdict(int)         self.not_found: Set[int] = set()-        self.msg_ids: Dict[int, Set[int]] = defaultdict(set)+        self.msg_ids: Dict[int, Dict[int, int]] = defaultdict(dict)

ok, but still naming is misleading, could bee renamed to msg_idxes

paul-nameless

comment created time in 12 days

Pull request review commentpaul-nameless/tg

Draft: adding lock to message update and using indexes for msgs

 def prev_msg(self, chat_id: int, step: int = 1) -> bool:         if new_idx < len(self.msgs[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]:-        msg_set = self.msg_ids[chat_id]-        if msg_id not in msg_set:-            # we are not storing any out of ordres old msgs-            # just fetching then on demand-            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-        return next(iter(m for m in self.msgs[chat_id] if m["id"] == msg_id))--    def remove_message(self, chat_id: int, msg_id: int):-        msg_set = self.msg_ids[chat_id]-        if msg_id not in msg_set:-            return False-        log.info(f"removing msg {msg_id=}")-        # FIXME: potential bottleneck, replace with constan time operation-        self.msgs[chat_id] = [-            m for m in self.msgs[chat_id] if m["id"] != msg_id-        ]-        msg_set.remove(msg_id)-        return True+        with self.lock:+            index = self.msg_ids[chat_id].get(msg_id)+            if index:+                return self.msgs[chat_id][index]+        # we are not storing any out of ordres old msgs+        # just fetching them on demand+        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_ids: List[int]):+        with self.lock:+            log.info(f"removing msg {msg_ids=}")+            self.msgs[chat_id] = [+                m for m in self.msgs[chat_id] if m["id"] not in msg_ids+            ]+            self.msg_ids[chat_id] = {+                msg["id"]: i for i, msg in enumerate(self.msgs[chat_id])+            }++    def add_message(self, chat_id: int, msg: Dict[str, Any]):+        with self.lock:+            log.info(f"adding {msg=}")+            self.msgs[chat_id].append(msg)+            self.msgs[chat_id] = sorted(

you can add condition here and sort only when msg['id'] < self.msgs[chat_id][-1]['id']

paul-nameless

comment created time in 12 days

Pull request review commentpaul-nameless/tg

Draft: adding lock to message update and using indexes for msgs

 def __init__(self, tg: Tdlib):         self.msgs: Dict[int, List[Dict]] = defaultdict(list)         self.current_msgs: Dict[int, int] = defaultdict(int)         self.not_found: Set[int] = set()-        self.msg_ids: Dict[int, Set[int]] = defaultdict(set)+        self.msg_ids: Dict[int, Dict[int, int]] = defaultdict(dict)

oh, ignore me, i can see this dict stores IDs only, but not messages itself

paul-nameless

comment created time in 12 days

Pull request review commentpaul-nameless/tg

Draft: adding lock to message update and using indexes for msgs

 def prev_msg(self, chat_id: int, step: int = 1) -> bool:         if new_idx < len(self.msgs[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]:-        msg_set = self.msg_ids[chat_id]-        if msg_id not in msg_set:-            # we are not storing any out of ordres old msgs-            # just fetching then on demand-            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-        return next(iter(m for m in self.msgs[chat_id] if m["id"] == msg_id))--    def remove_message(self, chat_id: int, msg_id: int):-        msg_set = self.msg_ids[chat_id]-        if msg_id not in msg_set:-            return False-        log.info(f"removing msg {msg_id=}")-        # FIXME: potential bottleneck, replace with constan time operation-        self.msgs[chat_id] = [-            m for m in self.msgs[chat_id] if m["id"] != msg_id-        ]-        msg_set.remove(msg_id)-        return True+        with self.lock:+            index = self.msg_ids[chat_id].get(msg_id)+            if index:

you could use warsul operator to remove extra line

paul-nameless

comment created time in 12 days

Pull request review commentpaul-nameless/tg

Draft: adding lock to message update and using indexes for msgs

 def __init__(self, tg: Tdlib):         self.msgs: Dict[int, List[Dict]] = defaultdict(list)         self.current_msgs: Dict[int, int] = defaultdict(int)         self.not_found: Set[int] = set()-        self.msg_ids: Dict[int, Set[int]] = defaultdict(set)+        self.msg_ids: Dict[int, Dict[int, int]] = defaultdict(dict)

naming could be improved. it stores not only msg IDs. could be renamed to msg_storage like it is done in https://github.com/zhukov/webogram/blob/master/app/js/messages_manager.js#L13

paul-nameless

comment created time in 12 days

issue commentpaul-nameless/tg

Voice recording buggy

@IvoLeist plz, clone with HTTPS instead of SSH: git clone https://github.com/paul-nameless/tg.git

IvoLeist

comment created time in 13 days

Pull request review commentpaul-nameless/tg

Show unseen flag in chat pane

 def interrupt_signal_handler(sig, frame):      model = Model(tg)     status_view = StatusView(stdscr)-    msg_view = MsgView(stdscr, model.msgs, model, model.users)

I found this approach more explicit and more flexible for future refactoring(removing Model class). Let's pass only what we need.

paul-nameless

comment created time in 13 days

Pull request review commentpaul-nameless/tg

Add AUR package info to README

 Docker (voice recordings and notifications won't work): docker run -it --rm tg ``` +Arch Linux users can install from the AUR: https://aur.archlinux.org/packages/telegram-tg-git/++```bash+yay -S telegram-tg-git+```+ ## Optional dependencies -- `terminal-notifier` or other program for notifications (see configuration)-- `ffmpeg` to record voice msgs and upload videos correctly+- [terminal-notifier](https://github.com/julienXX/terminal-notifier) for Mac, [dunst](https://github.com/dunst-project/dunst) for Linux or other program for notifications (see configuration)

done

lightme16

comment created time in 14 days

push eventpaul-nameless/tg

Alex

commit sha 11b20c4ce8026c7815270fa56353719e92ef0371

Update README

view details

push time in 14 days

issue commentpaul-nameless/tg

Voice recording buggy

Hey @IvoLeist.

VOICE_RECORD_CMD = "ffmpeg -f alsa -i hw:0 -c:a libopus -b:a 32k {file_path}"

this command is also works good to me, we can consider using it as default one for Linux.

regarding you next problem, can you clarify plz how did you install app? Can you plz try to install it from source with:

git clone git@github.com:paul-nameless/tg.git
cd tg
PYTHONPATH=. python3 tg/main.py

and reproduce the error?

from you error code:

[NULL @ 0x558585020e00] Unable to find a suitable output format for '/tmp/voice-2020-06-23'
/tmp/voice-2020-06-23: Invalid argument

I can see that there problem in quoting output record name, I believe it could be fixed in the https://github.com/paul-nameless/tg/pull/83

IvoLeist

comment created time in 14 days

issue commentpaul-nameless/tg

AUR package

Hey, @jugendhacker, thanks for your help! I checked your AUR and it works good for me :+1: I happy to mention about it in the README https://github.com/paul-nameless/tg/pull/88

jugendhacker

comment created time in 14 days

PR opened paul-nameless/tg

Reviewers
Add AUR package info to README

Mention about AUR package in the README See https://github.com/paul-nameless/tg/issues/87

+9 -3

0 comment

1 changed file

pr created time in 14 days

create barnchpaul-nameless/tg

branch : aur-to-readme

created branch time in 14 days

more