├── docs
├── LICENSE
└── README.md
├── poetry.lock
├── pyproject.toml
├── requirements.txt
├── src
├── Client.py
├── Management.py
├── Server.py
└── images
│ ├── icon.ico
│ ├── logo.png
│ ├── server.ico
│ └── server.png
├── tests
└── __init__.py
├── version.txt
└── view
├── dle.jpg
└── dlp.jpg
/docs/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Shervin Badanara
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Chat App
6 |
7 | Operating System | Version | Download
8 | ------------- | ------------- | -------------
9 | Windows 11 | Latest 2.1.4 | [64Bit](https://codeload.github.com/shervinbdndev/ChatApp/zip/refs/heads/64-bit)
10 | Windows 10 | Latest 2.1.4 | [64Bit](https://codeload.github.com/shervinbdndev/ChatApp/zip/refs/heads/64-bit) , [32Bit](https://codeload.github.com/shervinbdndev/ChatApp/zip/refs/heads/32-bit)
11 |
12 |
13 |
14 |
15 | A Windows Open Source Chat Application For Your Home Routers.
16 |
17 |
18 |
19 |
20 |
English Dark & Light Modes
21 |

22 |
23 |
24 |
Persian Dark & Light Modes
25 |

26 |
27 |
28 |
29 |
30 |
31 | Precendences
32 |
33 | - [x] Able To Run Server
34 | - [x] Able To Chat With Everyone
35 | - [x] Able To Switch Between Languages (Persian & English)
36 | - [x] Theme Synchronization
37 |
38 |
39 |
40 | Language and technologies used in This Project
41 |
42 |
43 |
44 |
45 |
46 |
47 | WorkSpace
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | How To Run
57 |
58 | First of All Clone the project from here ``~ git clone https://github.com/shervinbdndev/ChatApp.git``
59 |
60 |
61 |
62 | Then go To Project's Directory with ``~ cd ChatApp-master``
63 |
64 |
65 |
66 | For Running in Python Console 👇
67 |
68 |
69 |
70 | Windows : `` py -m pip install -r requirements.txt `` & `` cd .\src\ ``
71 |
72 |
73 |
74 | First Run The Server 👇
75 |
76 |
77 |
78 | ```py
79 | ~ py Server.py
80 | ```
81 |
82 |
83 | Then Client 👇
84 |
85 |
86 |
87 | ```py
88 | ~ py Client.py
89 | ```
--------------------------------------------------------------------------------
/poetry.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "atomicwrites"
3 | version = "1.4.0"
4 | description = "Atomic file writes."
5 | category = "dev"
6 | optional = false
7 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
8 |
9 | [[package]]
10 | name = "attrs"
11 | version = "21.4.0"
12 | description = "Classes Without Boilerplate"
13 | category = "dev"
14 | optional = false
15 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
16 |
17 | [package.extras]
18 | dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
19 | docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
20 | tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
21 | tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
22 |
23 | [[package]]
24 | name = "certifi"
25 | version = "2022.6.15"
26 | description = "Python package for providing Mozilla's CA Bundle."
27 | category = "main"
28 | optional = false
29 | python-versions = ">=3.6"
30 |
31 | [[package]]
32 | name = "charset-normalizer"
33 | version = "2.0.12"
34 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
35 | category = "main"
36 | optional = false
37 | python-versions = ">=3.5.0"
38 |
39 | [package.extras]
40 | unicode_backport = ["unicodedata2"]
41 |
42 | [[package]]
43 | name = "colorama"
44 | version = "0.4.5"
45 | description = "Cross-platform colored terminal text."
46 | category = "dev"
47 | optional = false
48 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
49 |
50 | [[package]]
51 | name = "idna"
52 | version = "3.3"
53 | description = "Internationalized Domain Names in Applications (IDNA)"
54 | category = "main"
55 | optional = false
56 | python-versions = ">=3.5"
57 |
58 | [[package]]
59 | name = "more-itertools"
60 | version = "8.13.0"
61 | description = "More routines for operating on iterables, beyond itertools"
62 | category = "dev"
63 | optional = false
64 | python-versions = ">=3.5"
65 |
66 | [[package]]
67 | name = "packaging"
68 | version = "21.3"
69 | description = "Core utilities for Python packages"
70 | category = "dev"
71 | optional = false
72 | python-versions = ">=3.6"
73 |
74 | [package.dependencies]
75 | pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
76 |
77 | [[package]]
78 | name = "pluggy"
79 | version = "0.13.1"
80 | description = "plugin and hook calling mechanisms for python"
81 | category = "dev"
82 | optional = false
83 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
84 |
85 | [package.extras]
86 | dev = ["pre-commit", "tox"]
87 |
88 | [[package]]
89 | name = "py"
90 | version = "1.11.0"
91 | description = "library with cross-python path, ini-parsing, io, code, log facilities"
92 | category = "dev"
93 | optional = false
94 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
95 |
96 | [[package]]
97 | name = "pyparsing"
98 | version = "3.0.9"
99 | description = "pyparsing module - Classes and methods to define and execute parsing grammars"
100 | category = "dev"
101 | optional = false
102 | python-versions = ">=3.6.8"
103 |
104 | [package.extras]
105 | diagrams = ["railroad-diagrams", "jinja2"]
106 |
107 | [[package]]
108 | name = "pytest"
109 | version = "5.4.3"
110 | description = "pytest: simple powerful testing with Python"
111 | category = "dev"
112 | optional = false
113 | python-versions = ">=3.5"
114 |
115 | [package.dependencies]
116 | atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
117 | attrs = ">=17.4.0"
118 | colorama = {version = "*", markers = "sys_platform == \"win32\""}
119 | more-itertools = ">=4.0.0"
120 | packaging = "*"
121 | pluggy = ">=0.12,<1.0"
122 | py = ">=1.5.0"
123 | wcwidth = "*"
124 |
125 | [package.extras]
126 | checkqa-mypy = ["mypy (==v0.761)"]
127 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
128 |
129 | [[package]]
130 | name = "requests"
131 | version = "2.28.0"
132 | description = "Python HTTP for Humans."
133 | category = "main"
134 | optional = false
135 | python-versions = ">=3.7, <4"
136 |
137 | [package.dependencies]
138 | certifi = ">=2017.4.17"
139 | charset-normalizer = ">=2.0.0,<2.1.0"
140 | idna = ">=2.5,<4"
141 | urllib3 = ">=1.21.1,<1.27"
142 |
143 | [package.extras]
144 | socks = ["PySocks (>=1.5.6,!=1.5.7)"]
145 | use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
146 |
147 | [[package]]
148 | name = "urllib3"
149 | version = "1.26.9"
150 | description = "HTTP library with thread-safe connection pooling, file post, and more."
151 | category = "main"
152 | optional = false
153 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
154 |
155 | [package.extras]
156 | brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
157 | secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
158 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
159 |
160 | [[package]]
161 | name = "wcwidth"
162 | version = "0.2.5"
163 | description = "Measures the displayed width of unicode strings in a terminal"
164 | category = "dev"
165 | optional = false
166 | python-versions = "*"
167 |
168 | [metadata]
169 | lock-version = "1.1"
170 | python-versions = "^3.9"
171 | content-hash = "0785b2c54043aaa53d7d2d9b1b7ecdd29dd2d8608eaf8ddf64395de36e60a8aa"
172 |
173 | [metadata.files]
174 | atomicwrites = [
175 | {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
176 | {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
177 | ]
178 | attrs = [
179 | {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
180 | {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
181 | ]
182 | certifi = [
183 | {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"},
184 | {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"},
185 | ]
186 | charset-normalizer = [
187 | {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"},
188 | {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"},
189 | ]
190 | colorama = [
191 | {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
192 | {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
193 | ]
194 | idna = [
195 | {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
196 | {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
197 | ]
198 | more-itertools = [
199 | {file = "more-itertools-8.13.0.tar.gz", hash = "sha256:a42901a0a5b169d925f6f217cd5a190e32ef54360905b9c39ee7db5313bfec0f"},
200 | {file = "more_itertools-8.13.0-py3-none-any.whl", hash = "sha256:c5122bffc5f104d37c1626b8615b511f3427aa5389b94d61e5ef8236bfbc3ddb"},
201 | ]
202 | packaging = [
203 | {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
204 | {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
205 | ]
206 | pluggy = [
207 | {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
208 | {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
209 | ]
210 | py = [
211 | {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
212 | {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
213 | ]
214 | pyparsing = [
215 | {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
216 | {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
217 | ]
218 | pytest = [
219 | {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"},
220 | {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"},
221 | ]
222 | requests = [
223 | {file = "requests-2.28.0-py3-none-any.whl", hash = "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f"},
224 | {file = "requests-2.28.0.tar.gz", hash = "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b"},
225 | ]
226 | urllib3 = [
227 | {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
228 | {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
229 | ]
230 | wcwidth = [
231 | {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
232 | {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
233 | ]
234 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "ChatApp"
3 | version = "2.1.4"
4 | description = ""
5 | authors = ["shervinbdndev "]
6 |
7 | [tool.poetry.dependencies]
8 | python = "^3.9"
9 | requests = "^2.28.0"
10 |
11 | [tool.poetry.dev-dependencies]
12 | pytest = "^5.2"
13 |
14 | [build-system]
15 | requires = ["poetry-core>=1.0.0"]
16 | build-backend = "poetry.core.masonry.api"
17 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | tk
2 | customtkinter
3 | sv_ttk
4 | sockets
5 | ntkutils
--------------------------------------------------------------------------------
/src/Client.py:
--------------------------------------------------------------------------------
1 | try:
2 | import os
3 | import sv_ttk
4 | import socket
5 | import tkinter
6 | import ntkutils
7 | import threading
8 | import webbrowser
9 | import darkdetect
10 | from typing_extensions import Self
11 | from tkinter.ttk import (Notebook , Frame)
12 | from tkinter.__init__ import (Text , StringVar)
13 | from customtkinter.widgets.customtkinter_entry import CTkEntry
14 | from customtkinter.widgets.customtkinter_button import CTkButton
15 |
16 | from Management import Materials
17 |
18 | except ModuleNotFoundError.__doc__ as mnfe:
19 | raise AttributeError(args='Cannot Run') from None
20 |
21 | finally:
22 | ...
23 |
24 |
25 |
26 |
27 |
28 | class Client:
29 | def __init__(self : Self) -> None:
30 | super(Client , self).__init__()
31 | self.root = tkinter.Tk()
32 | self.root.title(string=f'Client : {socket.gethostbyname(socket.gethostname())}')
33 | self.root.geometry(newGeometry='500x700')
34 | self.root.resizable(width=False , height=False)
35 | self.root.iconbitmap(bitmap=os.path.join(os.path.abspath(path=os.path.dirname(p=__file__)) , r'images/icon.ico'))
36 | self.tabControl = Notebook(master=self.root)
37 | self.tabChat = Frame(master=self.tabControl)
38 | self.tabLang = Frame(master=self.tabControl)
39 | self.tabAbout = Frame(master=self.tabControl)
40 | self.tabControl.add(child=self.tabChat , text='Chat')
41 | self.tabControl.add(child=self.tabLang , text='Language')
42 | self.tabControl.add(child=self.tabAbout , text='About')
43 | self.tabControl.pack(expand=1 , fill=Materials.Alignments.both)
44 | self.enMessage = StringVar(master=self.tabChat)
45 | self.clientSocket = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
46 | self.clientSocket.setsockopt(socket.SOL_SOCKET , socket.SO_REUSEADDR , 1)
47 | self.port: int = 8000
48 | self.hostIP: str = '127.0.0.1'
49 | self.clientSocket.connect((self.hostIP , self.port))
50 |
51 | def setBySystemTheme() -> None:
52 | if (darkdetect.isLight()):
53 | sv_ttk.set_theme(theme=Materials.Themes.LIGHT)
54 | self.textChat.configure(foreground=Materials.Colors.black)
55 | self.btnSend.configure(bg_color=Materials.Colors.white)
56 | self.btnPA.configure(bg_color=Materials.Colors.white)
57 | self.btnEN.configure(bg_color=Materials.Colors.white)
58 | self.btnGithub.configure(bg_color=Materials.Colors.white)
59 | self.root.update_idletasks()
60 | if (darkdetect.isDark()):
61 | sv_ttk.set_theme(theme=Materials.Themes.DARK)
62 | ntkutils.dark_title_bar(window=self.root)
63 | self.textChat.configure(foreground=Materials.Colors.white)
64 | self.btnSend.configure(bg_color=Materials.Colors.dark)
65 | self.btnPA.configure(bg_color=Materials.Colors.dark)
66 | self.btnEN.configure(bg_color=Materials.Colors.dark)
67 | self.btnGithub.configure(bg_color=Materials.Colors.dark)
68 | self.root.update_idletasks()
69 |
70 | def changeAppLanguage(arg : str) -> None:
71 | if (arg == 'PA'):
72 | self.root.title(string=f'دستگاه : {socket.gethostbyname(socket.gethostname())}')
73 | self.tabControl.add(child=self.tabChat , text='چت')
74 | self.tabControl.add(child=self.tabLang , text='زبان')
75 | self.tabControl.add(child=self.tabAbout , text='درباره')
76 | self.btnSend.configure(text='ارسال')
77 | self.btnPA.configure(text='پارسی')
78 | self.btnEN.configure(text='انگلیسی')
79 | self.btnGithub.configure(text='گیتهاب')
80 | if (self.enMessage.get() == ''):
81 | pass
82 | else:
83 | self.enMessage.set(value='پیام خود را وارد کنید')
84 | elif (arg == 'EN'):
85 | self.root.title(string=f'Client : {socket.gethostbyname(socket.gethostname())}')
86 | self.tabControl.add(child=self.tabChat , text='Chat')
87 | self.tabControl.add(child=self.tabLang , text='Language')
88 | self.tabControl.add(child=self.tabAbout , text='About')
89 | self.btnSend.configure(text='Send')
90 | self.btnPA.configure(text='Persian')
91 | self.btnEN.configure(text='English')
92 | self.btnGithub.configure(text='Github')
93 | if (self.enMessage.get() == ''):
94 | pass
95 | else:
96 | self.enMessage.set(value='Type Your Message Here')
97 |
98 | def aboutMeClickEvent() -> None:
99 | webbrowser.open(url='https://github.com/shervinbdndev')
100 |
101 | def sendMessage() -> None:
102 | msg = self.enMessage.get()
103 | self.textChat.insert(index=tkinter.END , chars=f"\n You: {msg}")
104 | self.clientSocket.send(msg.encode(encoding='utf-8'))
105 |
106 | def receiveMessage() -> None:
107 | while True:
108 | serverMessage = self.clientSocket.recv(1024).decode(encoding='utf-8')
109 | self.textChat.insert(index=tkinter.END , chars=f"\n {serverMessage}")
110 |
111 | def startRecieveing() -> None:
112 | recv = threading.Thread(target=receiveMessage)
113 | recv.daemon = True
114 | recv.start()
115 |
116 | self.textChat = Text(
117 | master=self.tabChat ,
118 | width=53 ,
119 | height=31 ,
120 | bd=1 ,
121 | border=1 ,
122 | borderwidth=1 ,
123 | font=(Materials.Fonts.pop , 12 , Materials.FontWeight.bold) ,
124 | relief=Materials.Reliefs.groove ,
125 | highlightcolor=Materials.Colors.medPurple ,
126 | highlightbackground=Materials.Colors.medPurple ,
127 | highlightthickness=1 ,
128 | )
129 |
130 | self.textChat.place(relx=0.5 , rely=0.46 , anchor=Materials.Alignments.center)
131 |
132 | self.entryMessage = CTkEntry(
133 | master=self.tabChat ,
134 | textvariable=self.enMessage ,
135 | corner_radius=5 ,
136 | width=363 ,
137 | height=40 ,
138 | text_color=Materials.Colors.medPurple ,
139 | text_font=(Materials.FontWeight.bold) ,
140 | cursor=Materials.Cursors.hand ,
141 | justify=Materials.Alignments.left ,
142 | border_color=Materials.Colors.medPurple ,
143 | state=Materials.State.normal ,
144 | )
145 |
146 | self.enMessage.set(value='Type Your Message Here')
147 |
148 | self.entryMessage.place(relx=0.377 , rely=0.95452 , anchor=Materials.Alignments.center)
149 |
150 | self.btnSend = CTkButton(
151 | master=self.tabChat ,
152 | text='Send' ,
153 | corner_radius=5 ,
154 | width=100 ,
155 | height=40 ,
156 | text_color=Materials.Colors.white ,
157 | text_font=(Materials.FontWeight.bold) ,
158 | fg_color=Materials.Colors.medPurple ,
159 | cursor=Materials.Cursors.hand ,
160 | state=Materials.State.normal ,
161 | command=sendMessage,
162 | )
163 |
164 | self.btnSend.place(relx=0.882 , rely=0.95452 , anchor=Materials.Alignments.center)
165 |
166 | self.btnPA = CTkButton(
167 | master=self.tabLang ,
168 | text='Persian' ,
169 | corner_radius=5 ,
170 | width=200 ,
171 | height=60 ,
172 | text_color=Materials.Colors.white ,
173 | text_font=(Materials.FontWeight.bold) ,
174 | fg_color=Materials.Colors.medPurple ,
175 | cursor=Materials.Cursors.hand ,
176 | state=Materials.State.normal ,
177 | command=lambda:changeAppLanguage(arg='PA'),
178 | )
179 |
180 | self.btnPA.place(relx=0.25 , rely=0.5 , anchor=Materials.Alignments.center)
181 |
182 | self.btnEN = CTkButton(
183 | master=self.tabLang ,
184 | text='English' ,
185 | corner_radius=5 ,
186 | width=200 ,
187 | height=60 ,
188 | text_color=Materials.Colors.white ,
189 | text_font=(Materials.FontWeight.bold) ,
190 | fg_color=Materials.Colors.medPurple ,
191 | cursor=Materials.Cursors.hand ,
192 | state=Materials.State.normal ,
193 | command=lambda:changeAppLanguage(arg='EN'),
194 | )
195 |
196 | self.btnEN.place(relx=0.75 , rely=0.5 , anchor=Materials.Alignments.center)
197 |
198 | self.btnGithub = CTkButton(
199 | master=self.tabAbout ,
200 | text='Github' ,
201 | corner_radius=5 ,
202 | width=200 ,
203 | height=60 ,
204 | text_color=Materials.Colors.white ,
205 | text_font=(Materials.FontWeight.bold) ,
206 | fg_color=Materials.Colors.medPurple ,
207 | cursor=Materials.Cursors.hand ,
208 | state=Materials.State.normal ,
209 | command=aboutMeClickEvent,
210 | )
211 |
212 | self.btnGithub.place(relx=0.5 , rely=0.5 , anchor=Materials.Alignments.center)
213 |
214 | setBySystemTheme()
215 | startRecieveing()
216 |
217 | self.root.mainloop()
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 | def main() -> None:
226 | Client()
227 |
228 |
229 |
230 |
231 |
232 | if (__name__ == '__main__' and __package__ is None):
233 | main()
--------------------------------------------------------------------------------
/src/Management.py:
--------------------------------------------------------------------------------
1 | try:
2 | from tkinter.font import BOLD
3 | from dataclasses import dataclass
4 | from tkinter.constants import (CENTER , NORMAL , BOTH , GROOVE , LEFT)
5 |
6 | except ModuleNotFoundError.__doc__ as mnfe:
7 | raise AttributeError(args='Cannot Import Materials') from None
8 |
9 | finally:
10 | ...
11 |
12 |
13 |
14 |
15 |
16 | @dataclass
17 | class Materials:
18 |
19 | @dataclass
20 | class Fonts:
21 | pop: str = 'Poplar Std'
22 |
23 | @dataclass
24 | class State:
25 | normal: str = NORMAL
26 |
27 | @dataclass
28 | class Cursors:
29 | hand: str = 'hand2'
30 |
31 | @dataclass
32 | class FontWeight:
33 | bold: str = BOLD
34 |
35 | @dataclass
36 | class Reliefs:
37 | groove: str = GROOVE
38 |
39 | @dataclass
40 | class Themes:
41 | DARK: str = 'dark'
42 | LIGHT: str = 'light'
43 |
44 | @dataclass
45 | class Colors:
46 | dark: str = '#1C1C1C'
47 | white: str = '#ffffff'
48 | black: str = '#000000'
49 | medPurple: str = '#5964e5'
50 |
51 | @dataclass
52 | class Alignments:
53 | both: str = BOTH
54 | left: str = LEFT
55 | center: str = CENTER
--------------------------------------------------------------------------------
/src/Server.py:
--------------------------------------------------------------------------------
1 | try:
2 | import socket as skt
3 | from socket import socket
4 | from threading import Thread
5 | from dataclasses import dataclass
6 | from typing_extensions import Self
7 |
8 | except ModuleNotFoundError.__doc__ as mnfe:
9 | raise AttributeError(args='Cannot Run Server') from None
10 |
11 | finally:
12 | ...
13 |
14 |
15 |
16 |
17 | @dataclass
18 | class Users:
19 | clients = set()
20 |
21 |
22 |
23 |
24 |
25 | def clientThread(clientSocket : socket , clientAddress) -> None:
26 | while True:
27 | msg = clientSocket.recv(1024).decode(encoding='utf-8')
28 | print(f'{clientAddress[0]} : {str(clientAddress[1])} says: {msg}')
29 | for client in Users.clients:
30 | if (client is not clientSocket):
31 | client.send((f'{clientAddress[0]} : {str(clientAddress[1])} says: {msg}').encode(encoding='utf-8'))
32 | if (not msg):
33 | Users.clients.remove(clientSocket)
34 | print((f'{clientAddress[0]} : {str(clientAddress[1])} says: {msg}').encode(encoding='utf-8'))
35 | break
36 | clientSocket.close()
37 |
38 |
39 | hostSocket = socket(skt.AF_INET , skt.SOCK_STREAM)
40 | hostSocket.setsockopt(skt.SOL_SOCKET , skt.SO_REUSEADDR , 1)
41 |
42 |
43 | hostSocket.bind(('127.0.0.1' , 8000))
44 | hostSocket.listen(1)
45 | print('Waiting For Connection . . .')
46 |
47 |
48 | if (__name__ == '__main__' and __package__ is None):
49 | while True:
50 | clientSocket , clientAddress = hostSocket.accept()
51 | Users.clients.add(clientSocket)
52 | print(f"Connection Stablished With: {clientAddress[0]} : {clientAddress[1]}")
53 | th = Thread(target=clientThread , args=(clientSocket , clientAddress , ))
54 | th.start()
--------------------------------------------------------------------------------
/src/images/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shervinbdndev/ChatApp/ceb95b74315ad021e01d48f9e25daa16af816df1/src/images/icon.ico
--------------------------------------------------------------------------------
/src/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shervinbdndev/ChatApp/ceb95b74315ad021e01d48f9e25daa16af816df1/src/images/logo.png
--------------------------------------------------------------------------------
/src/images/server.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shervinbdndev/ChatApp/ceb95b74315ad021e01d48f9e25daa16af816df1/src/images/server.ico
--------------------------------------------------------------------------------
/src/images/server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shervinbdndev/ChatApp/ceb95b74315ad021e01d48f9e25daa16af816df1/src/images/server.png
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shervinbdndev/ChatApp/ceb95b74315ad021e01d48f9e25daa16af816df1/tests/__init__.py
--------------------------------------------------------------------------------
/version.txt:
--------------------------------------------------------------------------------
1 | 2.1.4
--------------------------------------------------------------------------------
/view/dle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shervinbdndev/ChatApp/ceb95b74315ad021e01d48f9e25daa16af816df1/view/dle.jpg
--------------------------------------------------------------------------------
/view/dlp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shervinbdndev/ChatApp/ceb95b74315ad021e01d48f9e25daa16af816df1/view/dlp.jpg
--------------------------------------------------------------------------------