mastui 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mastui-0.3.0/LICENSE +21 -0
- mastui-0.3.0/PKG-INFO +98 -0
- mastui-0.3.0/README.md +77 -0
- mastui-0.3.0/mastui/__init__.py +0 -0
- mastui-0.3.0/mastui/app.css +302 -0
- mastui-0.3.0/mastui/app.py +275 -0
- mastui-0.3.0/mastui/config.py +35 -0
- mastui-0.3.0/mastui/logging_config.py +13 -0
- mastui-0.3.0/mastui/login.py +76 -0
- mastui-0.3.0/mastui/mastodon_api.py +86 -0
- mastui-0.3.0/mastui/messages.py +48 -0
- mastui-0.3.0/mastui/post.py +61 -0
- mastui-0.3.0/mastui/profile.py +107 -0
- mastui-0.3.0/mastui/reply.py +90 -0
- mastui-0.3.0/mastui/splash.py +58 -0
- mastui-0.3.0/mastui/thread.py +159 -0
- mastui-0.3.0/mastui/timeline.py +287 -0
- mastui-0.3.0/mastui/utils.py +50 -0
- mastui-0.3.0/mastui/widgets.py +195 -0
- mastui-0.3.0/pyproject.toml +27 -0
mastui-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Kim Schulz
|
|
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.
|
mastui-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: mastui
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: A Mastodon TUI client.
|
|
5
|
+
Author: Kim Schulz
|
|
6
|
+
Requires-Python: >=3.9,<4.0
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Requires-Dist: html2text (>=2024.2.26,<2025.0.0)
|
|
13
|
+
Requires-Dist: mastodon-py (>=2.0.1,<3.0.0)
|
|
14
|
+
Requires-Dist: pyperclip (>=1.8.2,<2.0.0)
|
|
15
|
+
Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
|
|
16
|
+
Requires-Dist: requests (>=2.32.4,<3.0.0)
|
|
17
|
+
Requires-Dist: textual (>=0.59.0)
|
|
18
|
+
Requires-Dist: toml (>=0.10.2,<0.11.0)
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# Mastui - A Mastodon TUI Client Built with Python
|
|
22
|
+
|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
Mastui is a Mastodon TUI client built with Python and Textual. It allows users to interact with their Mastodon instance in a terminal environment, providing a more efficient and intuitive way of managing their Mastodon experience. The UI is multi-column to get an easy overview of activities.
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
* Timeline Viewing in a multi-column layout
|
|
30
|
+
* Post and Reply creation
|
|
31
|
+
* "Infinite" scrolling of timelines
|
|
32
|
+
* Like posts
|
|
33
|
+
* View user profiles
|
|
34
|
+
* Follow/Unfollow users
|
|
35
|
+
* View post threads
|
|
36
|
+
* Support for local Mastodon servers
|
|
37
|
+
* Light/Dark mode theming
|
|
38
|
+
* Content warning support
|
|
39
|
+
|
|
40
|
+
### TODO
|
|
41
|
+
|
|
42
|
+
* database backend
|
|
43
|
+
* Bookmarking
|
|
44
|
+
* Hashtag Searching
|
|
45
|
+
* Unliking posts
|
|
46
|
+
* Direct Messaging
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
The recommended way to install Mastui is with `pipx`.
|
|
51
|
+
|
|
52
|
+
1. **Install pipx** (if you don't have it already):
|
|
53
|
+
```bash
|
|
54
|
+
python3 -m pip install --user pipx
|
|
55
|
+
python3 -m pipx ensurepath
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
2. **Install mastui using pipx**:
|
|
59
|
+
```bash
|
|
60
|
+
pipx install mastui
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
After this, you can run the application from anywhere by simply typing `mastui`.
|
|
64
|
+
|
|
65
|
+
## Technology Stack
|
|
66
|
+
|
|
67
|
+
* [Python](https://www.python.org/)
|
|
68
|
+
* [Poetry](https://python-poetry.org/) for dependency management
|
|
69
|
+
* [Textual](https://textual.textualize.io/) for the TUI framework
|
|
70
|
+
* [Mastodon.py](https://mastodonpy.readthedocs.io/) for interacting with the Mastodon API
|
|
71
|
+
* [html2text](https://github.com/Alir3z4/html2text) for converting HTML to Markdown
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
Mastui is licensed under the MIT license. See LICENSE for more information.
|
|
76
|
+
|
|
77
|
+
## Contributing
|
|
78
|
+
|
|
79
|
+
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
|
|
80
|
+
|
|
81
|
+
## Versioning
|
|
82
|
+
|
|
83
|
+
We use SemVer for versioning. For the versions available, see the tags on this repository.
|
|
84
|
+
|
|
85
|
+
## Authors
|
|
86
|
+
|
|
87
|
+
* **Kim Schulz** - *Initial work* - [kimusan](https://github.com/kimusan)
|
|
88
|
+
|
|
89
|
+
See also the list of contributors who participated in this project.
|
|
90
|
+
|
|
91
|
+
## Acknowledgments
|
|
92
|
+
|
|
93
|
+
* Inspiration and guidance from the Textual community and the Poetry team
|
|
94
|
+
* The Mastodon community for their contributions to the development of the application and its features
|
|
95
|
+
* Other projects that have inspired or influenced the design of Mastui
|
|
96
|
+
|
|
97
|
+
Please feel free to reach out to me if you have any questions, comments, or concerns.
|
|
98
|
+
|
mastui-0.3.0/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Mastui - A Mastodon TUI Client Built with Python
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Mastui is a Mastodon TUI client built with Python and Textual. It allows users to interact with their Mastodon instance in a terminal environment, providing a more efficient and intuitive way of managing their Mastodon experience. The UI is multi-column to get an easy overview of activities.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
* Timeline Viewing in a multi-column layout
|
|
10
|
+
* Post and Reply creation
|
|
11
|
+
* "Infinite" scrolling of timelines
|
|
12
|
+
* Like posts
|
|
13
|
+
* View user profiles
|
|
14
|
+
* Follow/Unfollow users
|
|
15
|
+
* View post threads
|
|
16
|
+
* Support for local Mastodon servers
|
|
17
|
+
* Light/Dark mode theming
|
|
18
|
+
* Content warning support
|
|
19
|
+
|
|
20
|
+
### TODO
|
|
21
|
+
|
|
22
|
+
* database backend
|
|
23
|
+
* Bookmarking
|
|
24
|
+
* Hashtag Searching
|
|
25
|
+
* Unliking posts
|
|
26
|
+
* Direct Messaging
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
The recommended way to install Mastui is with `pipx`.
|
|
31
|
+
|
|
32
|
+
1. **Install pipx** (if you don't have it already):
|
|
33
|
+
```bash
|
|
34
|
+
python3 -m pip install --user pipx
|
|
35
|
+
python3 -m pipx ensurepath
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. **Install mastui using pipx**:
|
|
39
|
+
```bash
|
|
40
|
+
pipx install mastui
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
After this, you can run the application from anywhere by simply typing `mastui`.
|
|
44
|
+
|
|
45
|
+
## Technology Stack
|
|
46
|
+
|
|
47
|
+
* [Python](https://www.python.org/)
|
|
48
|
+
* [Poetry](https://python-poetry.org/) for dependency management
|
|
49
|
+
* [Textual](https://textual.textualize.io/) for the TUI framework
|
|
50
|
+
* [Mastodon.py](https://mastodonpy.readthedocs.io/) for interacting with the Mastodon API
|
|
51
|
+
* [html2text](https://github.com/Alir3z4/html2text) for converting HTML to Markdown
|
|
52
|
+
|
|
53
|
+
## License
|
|
54
|
+
|
|
55
|
+
Mastui is licensed under the MIT license. See LICENSE for more information.
|
|
56
|
+
|
|
57
|
+
## Contributing
|
|
58
|
+
|
|
59
|
+
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
|
|
60
|
+
|
|
61
|
+
## Versioning
|
|
62
|
+
|
|
63
|
+
We use SemVer for versioning. For the versions available, see the tags on this repository.
|
|
64
|
+
|
|
65
|
+
## Authors
|
|
66
|
+
|
|
67
|
+
* **Kim Schulz** - *Initial work* - [kimusan](https://github.com/kimusan)
|
|
68
|
+
|
|
69
|
+
See also the list of contributors who participated in this project.
|
|
70
|
+
|
|
71
|
+
## Acknowledgments
|
|
72
|
+
|
|
73
|
+
* Inspiration and guidance from the Textual community and the Poetry team
|
|
74
|
+
* The Mastodon community for their contributions to the development of the application and its features
|
|
75
|
+
* Other projects that have inspired or influenced the design of Mastui
|
|
76
|
+
|
|
77
|
+
Please feel free to reach out to me if you have any questions, comments, or concerns.
|
|
File without changes
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
Screen {
|
|
2
|
+
layout: vertical;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
Timelines {
|
|
6
|
+
layout: horizontal;
|
|
7
|
+
height: 1fr;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Timeline {
|
|
11
|
+
layout: vertical;
|
|
12
|
+
border: solid $accent;
|
|
13
|
+
width: 1fr;
|
|
14
|
+
height: 100%;
|
|
15
|
+
margin: 1;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.timeline-content {
|
|
19
|
+
/* This is now empty, as display is handled by the widget itself */
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Timeline:focus {
|
|
23
|
+
border: double $accent-darken-2;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.timeline-header {
|
|
27
|
+
height: 1;
|
|
28
|
+
background: $accent;
|
|
29
|
+
color: $text;
|
|
30
|
+
dock: top;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.timeline_title {
|
|
34
|
+
width: 1fr;
|
|
35
|
+
height: 1;
|
|
36
|
+
text-align: center;
|
|
37
|
+
padding: 0 1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.timeline-refresh-spinner {
|
|
41
|
+
dock: right;
|
|
42
|
+
width: auto;
|
|
43
|
+
height: 1;
|
|
44
|
+
display: none;
|
|
45
|
+
margin: 0 1;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.timeline-item {
|
|
49
|
+
height: auto;
|
|
50
|
+
margin-bottom: 1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.boost-header {
|
|
54
|
+
padding: 0 1;
|
|
55
|
+
background: $primary-darken-2;
|
|
56
|
+
color: $text;
|
|
57
|
+
height: 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
SplashScreen > Vertical {
|
|
61
|
+
align: center middle;
|
|
62
|
+
height: 100%;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
#logo {
|
|
67
|
+
width: auto;
|
|
68
|
+
height: auto;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#version {
|
|
72
|
+
width: auto;
|
|
73
|
+
text-align: center;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
#splash-status {
|
|
77
|
+
width: auto;
|
|
78
|
+
text-align: center;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.action-spinner {
|
|
82
|
+
display: none;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
.post-footer {
|
|
87
|
+
height: 1;
|
|
88
|
+
padding: 0 1;
|
|
89
|
+
background: $surface-darken-1;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.post-footer > Static {
|
|
93
|
+
width: 1fr;
|
|
94
|
+
text-align: center;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.status-message {
|
|
98
|
+
margin-top: 1;
|
|
99
|
+
text-align: center;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
Post.favourited {
|
|
103
|
+
background: $success 20%;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Post.reblogged {
|
|
107
|
+
background: $warning 20%;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.timeline-item.selected {
|
|
111
|
+
background: $primary 20%;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
Post.selected {
|
|
115
|
+
background: $primary 20%;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
Notification.selected {
|
|
119
|
+
background: $primary 20%;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
#dialog {
|
|
124
|
+
grid-size: 2;
|
|
125
|
+
grid-gutter: 1;
|
|
126
|
+
align: center middle;
|
|
127
|
+
width: 80%;
|
|
128
|
+
height: auto;
|
|
129
|
+
max-height: 80%;
|
|
130
|
+
background: $surface;
|
|
131
|
+
border: thick $primary 80%;
|
|
132
|
+
padding: 1;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
#dialog > .hidden {
|
|
136
|
+
display: none;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#auth_link_container {
|
|
140
|
+
column-span: 2;
|
|
141
|
+
margin-top: 1;
|
|
142
|
+
border: round $primary;
|
|
143
|
+
padding: 1;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
#auth_link_container > TextArea {
|
|
147
|
+
height: 5;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
#auth_link_container.hidden {
|
|
151
|
+
display: none;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
#status {
|
|
155
|
+
column-span: 2;
|
|
156
|
+
text-align: center;
|
|
157
|
+
color: $error;
|
|
158
|
+
height: auto;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
#status.hidden {
|
|
162
|
+
display: none;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#post_dialog {
|
|
166
|
+
grid-size: 1;
|
|
167
|
+
grid-gutter: 1;
|
|
168
|
+
align: center middle;
|
|
169
|
+
width: 80%;
|
|
170
|
+
height: auto;
|
|
171
|
+
max-height: 80%;
|
|
172
|
+
background: $surface;
|
|
173
|
+
border: thick $primary 80%;
|
|
174
|
+
padding: 1;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
#post_title {
|
|
178
|
+
width: 100%;
|
|
179
|
+
text-align: center;
|
|
180
|
+
background: $primary;
|
|
181
|
+
color: $text;
|
|
182
|
+
padding: 0 1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
#post_content {
|
|
186
|
+
height: 10;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
#post_options {
|
|
190
|
+
height: auto;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
#post_language_container {
|
|
194
|
+
height: auto;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.post_option_label {
|
|
198
|
+
width: auto;
|
|
199
|
+
height: 100%;
|
|
200
|
+
content-align: left middle;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
#cw_input {
|
|
204
|
+
width: 1fr;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
#language_select {
|
|
208
|
+
width: 1fr;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
#post_buttons {
|
|
212
|
+
width: 100%;
|
|
213
|
+
align-horizontal: right;
|
|
214
|
+
height: auto;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
#post_buttons > Button {
|
|
218
|
+
margin-left: 1;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
#reply_dialog {
|
|
222
|
+
grid-size: 1;
|
|
223
|
+
grid-gutter: 1;
|
|
224
|
+
align: center middle;
|
|
225
|
+
width: 80%;
|
|
226
|
+
height: auto;
|
|
227
|
+
max-height: 90%;
|
|
228
|
+
background: $surface;
|
|
229
|
+
border: thick $primary 80%;
|
|
230
|
+
padding: 1;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
#reply_title {
|
|
234
|
+
width: 100%;
|
|
235
|
+
text-align: center;
|
|
236
|
+
background: $primary;
|
|
237
|
+
color: $text;
|
|
238
|
+
padding: 0 1;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
#original_post_preview {
|
|
242
|
+
height: auto;
|
|
243
|
+
max-height: 10;
|
|
244
|
+
overflow: auto;
|
|
245
|
+
margin-bottom: 1;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
#reply_content {
|
|
249
|
+
height: 10;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
#reply_options {
|
|
253
|
+
height: auto;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
#reply_language_container {
|
|
257
|
+
height: auto;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.reply_option_label {
|
|
261
|
+
width: auto;
|
|
262
|
+
height: 100%;
|
|
263
|
+
content-align: left middle;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
#cw_input {
|
|
267
|
+
width: 1fr;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
#language_select {
|
|
271
|
+
width: 1fr;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
#reply_buttons {
|
|
275
|
+
width: 100%;
|
|
276
|
+
align-horizontal: right;
|
|
277
|
+
height: auto;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
#reply_buttons > Button {
|
|
281
|
+
margin-left: 1;
|
|
282
|
+
}
|
|
283
|
+
#thread-dialog {
|
|
284
|
+
width: 80%;
|
|
285
|
+
height: 80%;
|
|
286
|
+
background: $surface;
|
|
287
|
+
border: thick $primary 80%;
|
|
288
|
+
padding: 1;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
#thread-container {
|
|
292
|
+
padding: 1;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.main-post {
|
|
296
|
+
border: round $accent;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.reply-post {
|
|
300
|
+
margin-left: 4;
|
|
301
|
+
}
|
|
302
|
+
|