2 # Copyright (C) 2019 Alex Schroeder <alex@gnu.org>
4 # This program is free software: you can redistribute it and/or modify it under
5 # the terms of the GNU Affero General Public License as published by the Free
6 # Software Foundation, either version 3 of the License, or (at your option) any
9 # This program is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
14 # You should have received a copy of the GNU Affero General Public License along
15 # with this program. If not, see <https://www.gnu.org/licenses/>.
25 # Command abbreviations
32 "~/.config/jan-pona-mute/login",
33 "~/.config/.jan-pona-mute",
45 for rc_path
in _RC_PATHS
:
46 rcfile
= os
.path
.expanduser(rc_path
)
47 if os
.path
.exists(rcfile
):
54 pager
= shutil
.which(cmd
)
58 class DiasporaClient(cmd
.Cmd
):
60 prompt
= "\x1b[38;5;255m" + "> " + "\x1b[0m"
61 intro
= "Welcome to Diaspora! Use the intro command for a quick introduction."
73 # dict mapping user ids to usernames
76 def get_username(self
, guid
):
77 if guid
in self
.users
:
78 return self
.users
[guid
]
80 user
= diaspy
.people
.User(connection
= self
.connection
, guid
= guid
)
81 self
.users
[guid
] = user
.handle()
82 return self
.users
[guid
]
84 def do_intro(self
, line
):
86 Use the account and password commands to set up your connection, then
87 use the login command to log in. If everything works as intended, use
88 the save command to save these commands to an init file.
90 Once you've listed things such as notifications, enter a number to
91 select the corresponding item. Use the print command to see more.
94 def do_account(self
, account
):
95 """Set username and pod using the format username@pod."""
97 (self
.username
, self
.pod
) = account
.split('@')
98 print("Username and pod set: %s@%s" % (self
.username
, self
.pod
))
100 print("The account must contain an @ character, e.g. kensanata@pluspora.com.")
101 print("Use the account comand to set the account.")
103 def do_info(self
, line
):
104 """Get some info about things. By default, it is info about yourself."""
105 print("Info about yourself:")
106 print("Username: %s" % self
.username
)
107 print("Password: %s" % ("None" if self
.password
== None else "set"))
108 print("Pod: %s" % self
.pod
)
109 print("Pager: %s" % self
.pager
)
111 def do_password(self
, password
):
112 """Set the password."""
113 self
.password
= (None if self
.password
== "" else password
)
114 print("Password %s" % ("unset" if self
.password
== "" else "set"))
116 def do_save(self
, line
):
117 if self
.username
== None or self
.pod
== None:
118 print("Use the account command to set username and pod")
119 elif self
.password
== None:
120 print("Use the password command")
122 rcfile
= get_rcfile()
124 rfile
= first(_RC_PATHS
)
126 seen_password
= False
130 with
open(rcfile
, "r") as fp
:
132 words
= line
.strip().split()
134 if words
[0] == "account":
136 account
= "%s@%s" % (self
.username
, self
.pod
)
137 if len(words
) > 1 and words
[1] != account
:
138 line
= "account %s\n" % account
140 elif words
[0] == "password":
142 if len(words
) > 1 and words
[1] != self
.password
:
143 line
= "password %s\n" % self
.password
145 elif words
[0] == "login":
146 if seen_account
and seen_password
:
149 # skip login if no account or no password given
155 file.append("account %s@%s\n" % (self
.username
, self
.pod
))
157 if not seen_password
:
158 file.append("password %s\n" % self
.password
)
161 file.append("login\n")
164 if os
.path
.isfile(rcfile
):
165 os
.rename(rcfile
, rcfile
+ "~")
166 if not os
.path
.isdir(os
.path
.dirname(rcfile
)):
167 os
.makedirs(os
.path
.dirname(rcfile
))
168 with
open(rcfile
, "w") as fp
:
169 fp
.write("".join(file))
170 print("Wrote %s" % rcfile
)
172 print("No changes made, %s left unchanged" % rcfile
)
174 def do_login(self
, line
):
177 self
.onecmd("account %s" % line
)
178 if self
.username
== None or self
.pod
== None:
179 print("Use the account command to set username and pod")
180 elif self
.password
== None:
181 print("Use the password command")
183 self
.connection
= diaspy
.connection
.Connection(
184 pod
= "https://%s" % self
.pod
, username
= self
.username
, password
= self
.password
)
186 self
.connection
.login()
187 self
.onecmd("notifications")
188 except diaspy
.errors
.LoginError
:
189 print("Login failed")
191 def do_pager(self
, pager
):
192 """Set the pager, e.g. to cat"""
194 print("Pager set: %s" % self
.pager
)
196 def do_notifications(self
, line
):
197 """List notifications."""
198 if self
.connection
== None:
199 print("Use the login command, first.")
201 self
.things
= diaspy
.notifications
.Notifications(self
.connection
).last()
202 for n
, notification
in enumerate(self
.things
):
203 print("%2d. %s %s" % (n
+1, notification
.when(), notification
))
204 print("Enter a number to select the notification.")
207 def do_quit(self
, *args
):
208 """Exit jan-pona-mute."""
212 def default(self
, line
):
213 if line
.strip() == "EOF":
214 return self
.onecmd("quit")
216 # Expand abbreviated commands
217 first_word
= line
.split()[0].strip()
218 if first_word
in _ABBREVS
:
219 full_cmd
= _ABBREVS
[first_word
]
220 expanded
= line
.replace(first_word
, full_cmd
, 1)
221 return self
.onecmd(expanded
)
223 # Try to parse numerical index for lookup table
225 n
= int(line
.strip())
227 print("Use the help command")
231 item
= self
.things
[n
-1]
233 print("Index too high!")
240 def show(self
, item
):
241 """Show the current item."""
243 subprocess
.run(self
.pager
, input = repr(item
), text
= True)
247 def do_print(self
, line
):
248 """Print more about the current item, or the item at the index given."""
252 n
= int(line
.strip())
254 print("The print argument takes an index as its argument")
257 print("Select an item by entering it's number")
259 item
= self
.things
[n
-1]
262 print("Index too high!")
265 item
= diaspy
.models
.Post(connection
= self
.connection
, id = item
.about())
272 parser
= argparse
.ArgumentParser(description
='A command line Diaspora client.')
273 parser
.add_argument('--no-init-file', dest
='init_file', action
='store_const',
274 const
=False, default
=True, help='Do not load a init file')
275 args
= parser
.parse_args()
283 rcfile
= get_rcfile()
285 print("Using init file %s" % rcfile
)
286 with
open(rcfile
, "r") as fp
:
290 c
.cmdqueue
.append(line
)
292 seen_pager
= line
.startswith("pager ");
294 print("Use the save command to save your login sequence to an init file")
298 c
.cmdqueue
.insert(0, "pager %s" % get_pager())
300 # Endless interpret loop
304 except KeyboardInterrupt:
307 if __name__
== '__main__':