Skip to content

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
vtr0n committed Mar 15, 2018
0 parents commit a9daf3f
Show file tree
Hide file tree
Showing 70 changed files with 10,966 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
.idea
__pycache__/
user.session
25 changes: 25 additions & 0 deletions README.md
@@ -0,0 +1,25 @@
## TelegramTUI
Telegram client on your console

![telegramtui](https://user-images.githubusercontent.com/18473198/37466210-410f5584-286e-11e8-9f5b-b1ce3d20e708.png)

#### Dependencies
* [Telethon](https://github.com/LonamiWebs/Telethon)
* [NpyScreen](https://github.com/bad-day/npyscreen)

#### Installation
`sudo apt-get install git python3 python3-pip`
`sudo pip3 install telethon`
`git clone https://github.com/bad-day/TelegramTUI`
`cd TelegramTUI`

#### Usage
* [Create application](https://core.telegram.org/api/obtaining_api_id)
* Put **api_id** and **api_hash** into **config.ini**
* Run `./telegramTUI`

#### Controls
* Navigation: `Tab`, `Shift+Tab`, `mouse`
* Send message: `Ctrl+S`, `Alt+Enter`
* Exit: `Ctrl+Q`, `ESC`
* Paste: `Shift+INS`
14 changes: 14 additions & 0 deletions config.ini
@@ -0,0 +1,14 @@
[telegram_api]
# get here: https://core.telegram.org/api/obtaining_api_id
api_id = *api_id here*
api_hash = *api_hash here*
# number of thread to receive data from tg api
workers = 3
# you can use few accounts, change it
session_name = user
[app]
name = TelegramTUI v0.6
message_dialog_len = 50
[other]
timezone = +3
emoji = True
115 changes: 115 additions & 0 deletions npyscreen/__init__.py
@@ -0,0 +1,115 @@
#!/usr/bin/python

from .globals import DEBUG, DISABLE_RESIZE_SYSTEM

from .wgwidget import TEST_SETTINGS, ExhaustedTestInput, add_test_input_from_iterable, add_test_input_ch

from .npyssafewrapper import wrapper, wrapper_basic

from .npysThemeManagers import ThemeManager, disableColor, enableColor
from . import npysThemes as Themes
from .apNPSApplication import NPSApp
from .apNPSApplicationManaged import NPSAppManaged
from .proto_fm_screen_area import setTheme
from .fmForm import FormBaseNew, Form, TitleForm, TitleFooterForm, SplitForm, FormExpanded, FormBaseNewExpanded, blank_terminal
from .fmActionForm import ActionForm, ActionFormExpanded
from .fmActionFormV2 import ActionFormV2, ActionFormExpandedV2, ActionFormMinimal
from .fmFormWithMenus import FormWithMenus, ActionFormWithMenus, \
FormBaseNewWithMenus, SplitFormWithMenus, \
ActionFormV2WithMenus
from .fmPopup import Popup, MessagePopup, ActionPopup, PopupWide, ActionPopupWide
from .fmFormMutt import FormMutt, FormMuttWithMenus
from .fmFileSelector import FileSelector, selectFile

from .fmFormMuttActive import ActionControllerSimple, TextCommandBox, \
FormMuttActive, FormMuttActiveWithMenus
from .fmFormMuttActive import FormMuttActiveTraditional, FormMuttActiveTraditionalWithMenus


from .fmFormMultiPage import FormMultiPage, FormMultiPageAction,\
FormMultiPageActionWithMenus, FormMultiPageWithMenus

from .npysNPSFilteredData import NPSFilteredDataBase, NPSFilteredDataList

from .wgbutton import MiniButton
from .wgbutton import MiniButtonPress
from .wgbutton import MiniButton as Button
from .wgbutton import MiniButtonPress as ButtonPress

from .wgtextbox import Textfield, FixedText
from .wgtitlefield import TitleText, TitleFixedText
from .wgpassword import PasswordEntry, TitlePassword
from .wgannotatetextbox import AnnotateTextboxBase
from .wgannotatetextbox import AnnotateTextboxBaseRight

from .wgslider import Slider, TitleSlider
from .wgslider import SliderNoLabel, TitleSliderNoLabel
from .wgslider import SliderPercent, TitleSliderPercent

from .wgwidget import DummyWidget, NotEnoughSpaceForWidget
from . import wgwidget as widget

from .wgmultiline import MultiLine, Pager, TitleMultiLine, TitlePager, MultiLineAction, BufferPager, TitleBufferPager
from .wgmultiselect import MultiSelect, TitleMultiSelect, MultiSelectFixed, \
TitleMultiSelectFixed, MultiSelectAction
from .wgeditmultiline import MultiLineEdit
from .wgcombobox import ComboBox, TitleCombo
from .wgcheckbox import Checkbox, RoundCheckBox, CheckBoxMultiline, RoundCheckBoxMultiline, CheckBox, CheckboxBare
from .wgFormControlCheckbox import FormControlCheckbox
from .wgautocomplete import TitleFilename, Filename, Autocomplete
from .muMenu import Menu
from .wgselectone import SelectOne, TitleSelectOne
from .wgdatecombo import DateCombo, TitleDateCombo

from .npysTree import TreeData
from .wgmultilinetree import MLTree, MLTreeAnnotated, MLTreeAction, MLTreeAnnotatedAction
from .wgmultilinetreeselectable import MLTreeMultiSelect, TreeLineSelectable
from .wgmultilinetreeselectable import MLTreeMultiSelectAnnotated, TreeLineSelectableAnnotated


# The following are maintained for compatibility with old code only. ##########################################

from .compatibility_code.oldtreeclasses import MultiLineTree, SelectOneTree
from .compatibility_code.oldtreeclasses import MultiLineTreeNew, MultiLineTreeNewAction, TreeLine, TreeLineAnnotated # Experimental
from .compatibility_code.oldtreeclasses import MultiLineTreeNewAnnotatedAction, MultiLineTreeNewAnnotated # Experimental
from .compatibility_code.npysNPSTree import NPSTreeData

# End compatibility. ###########################################################################################

from .wgfilenamecombo import FilenameCombo, TitleFilenameCombo
from .wgboxwidget import BoxBasic, BoxTitle
from .wgmultiline import MultiLineActionWithShortcuts
from .wgmultilineeditable import MultiLineEditable, MultiLineEditableTitle, MultiLineEditableBoxed

from .wgmonthbox import MonthBox
from .wggrid import SimpleGrid
from .wggridcoltitles import GridColTitles

from .muNewMenu import NewMenu, MenuItem
from .wgNMenuDisplay import MenuDisplay, MenuDisplayScreen

from .npyspmfuncs import CallSubShell

from .utilNotify import notify, notify_confirm, notify_wait, notify_ok_cancel, notify_yes_no

# Base classes for overriding:

# Standard Forms:
from . import stdfmemail

# Experimental Only
from .wgtextboxunicode import TextfieldUnicode
from .wgtexttokens import TextTokens, TitleTextTokens

# Very experimental. Don't use for anything serious
from .apOptions import SimpleOptionForm
from .apOptions import OptionListDisplay, OptionChanger, OptionList, OptionLimitedChoices, OptionListDisplayLine
from .apOptions import OptionFreeText, OptionSingleChoice, OptionMultiChoice, OptionMultiFreeList, \
OptionBoolean, OptionFilename, OptionDate, OptionMultiFreeText


# This really is about as experimental as it gets
from .apNPSApplicationEvents import StandardApp
from .eveventhandler import Event


32 changes: 32 additions & 0 deletions npyscreen/apNPSApplication.py
@@ -0,0 +1,32 @@
#!/usr/bin/env python
import curses
import locale
import _curses

from . import npyssafewrapper


class AlreadyOver(Exception):
pass

class NPSApp(object):
_run_called = 0
def main(self):
"""Overload this method to create your application"""

def resize(self):
pass

def __remove_argument_call_main(self, screen, enable_mouse=True):
# screen disgarded.
if enable_mouse:
curses.mousemask(curses.ALL_MOUSE_EVENTS)
del screen
return self.main()

def run(self, fork=None):
"""Run application. Calls Mainloop wrapped properly."""
if fork is None:
return npyssafewrapper.wrapper(self.__remove_argument_call_main)
else:
return npyssafewrapper.wrapper(self.__remove_argument_call_main, fork=fork)
13 changes: 13 additions & 0 deletions npyscreen/apNPSApplicationAdvanced.py
@@ -0,0 +1,13 @@
#!/usr/bin/env python
# encoding: utf-8

from . import apNPSApplicationManaged
from . import fmForm
import weakref

class NPSAppAdvanced(apNPSApplicationManaged.NPSAppManaged):
"""EXPERIMENTAL and NOT for use. This class of application will eventually replace the
standard method of user input handling and deal with everything at the application level."""

def _main_loop(self):
pass
75 changes: 75 additions & 0 deletions npyscreen/apNPSApplicationEvents.py
@@ -0,0 +1,75 @@
import collections
import weakref
from .apNPSApplicationManaged import NPSAppManaged
from .eveventhandler import EventHandler

class NPSEventQueue(object):
def __init__(self):
self.interal_queue = collections.deque()

def get(self, maximum=None):
if maximum is None:
maximum = -1
counter = 1
while counter != maximum:
try:
yield self.interal_queue.pop()
except IndexError:
raise StopIteration
counter += 1

def put(self, event):
self.interal_queue.append(event)

class StandardApp(NPSAppManaged, EventHandler):
MAINQUEUE_TYPE = NPSEventQueue
keypress_timeout_default = 2
max_events_per_queue = 50
"""This class adds event queue functionality to the existing NPSAppManaged. The name reflects the fact that future applications
are expected to use this class as standard. However, it is currently an experimental class. The API is unlikely to change, but
no promises are made at this time.
"""
def __init__(self):
super(StandardApp, self).__init__()
self.event_directory = {}
self.event_queues = {}
self.initalize_application_event_queues()
self.initialize_event_handling()

def _internal_while_waiting(self):
# Parent NPSAppManaged does not define this, so no need to call.
self.process_event_queues(max_events_per_queue=self.max_events_per_queue)


def initalize_application_event_queues(self):
# in the standard application the event queue is not threaded so...
main_queue = self.MAINQUEUE_TYPE()
self.event_queues['MAINQUEUE'] = main_queue

def process_event_queues(self, max_events_per_queue=None):
for queue in self.event_queues.values():
for event in queue.get(maximum=max_events_per_queue):
self.process_event(event)

def register_for_event(self, registering_object, event_name):
if event_name not in self.event_directory:
self.event_directory[event_name] = weakref.WeakSet()
self.event_directory[event_name].add(registering_object)

def queue_event(self, event, queue='MAINQUEUE'):
self.event_queues[queue].put(event)

def process_event(self, event):
discard_list = []
if event.name not in self.event_directory:
return True
if not self.event_directory[event.name]:
del self.event_directory[event.name]
return True
for registered_object in self.event_directory[event.name]:
result = registered_object.handle_event(event)
if result is False:
discard_list.append(registered_object)

for registered_object in discard_list:
self.event_directory[event.name].discard(registered_object)

0 comments on commit a9daf3f

Please sign in to comment.