forked from hupili/snsapi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
snscli.py
344 lines (271 loc) · 10.4 KB
/
snscli.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# -*- coding: utf-8 -*-
import snsapi
from snsapi import snstype
from snsapi.utils import console_output, console_input
from snsapi.snspocket import SNSPocket
from snsapi.snslog import SNSLog as logger
sp = SNSPocket()
def update_from_console(t, *al, **ad):
'''
A wrapper function to deal with user input from console.
String input from console is in console encoding. We must
first cast it to unicode, which is the standard across
SNSAPI.
'''
if isinstance(t, str):
return sp.update(console_input(t), *al, **ad)
elif isinstance(t, snstype.Message):
return sp.update(t, *al, **ad)
else:
logger.warning("unknown type: %s", type(t))
lc = load_config = lambda *al, **ad : sp.load_config(*al, **ad)
sc = save_config = lambda *al, **ad : sp.save_config(*al, **ad)
lsc = list_channel = lambda *al, **ad : sp.list_channel(*al, **ad)
lsp = list_platform = lambda *al, **ad : sp.list_platform(*al, **ad)
newc = new_channel = lambda *al, **ad : sp.new_channel(*al, **ad)
addc = add_channel = lambda *al, **ad : sp.add_channel(*al, **ad)
clc = clear_channel = lambda *al, **ad : sp.clear_channel(*al, **ad)
auth = lambda *al, **ad : sp.auth(*al, **ad)
ht = home_timeline = lambda *al, **ad : sp.home_timeline(*al, **ad)
up = update = lambda t, *al, **ad : update_from_console(t, *al, **ad)
re = reply = lambda m, t, *al, **ad : sp.reply(m, console_input(t), *al, **ad)
fwd = forward = lambda m, t, *al, **ad : sp.forward(m, console_input(t), *al, **ad)
#==== documentation ====
helpdoc = \
"""
snscli -- the interactive CLI to operate all SNS!
Type "print helpdoc" again to see this document.
To start your new journey, type "print tut"
Here's the command list:
* load_config
* save_config
* list
* auth
* home_timeline
* update
* reply
* new_channel
"""
class SNSAPITutorial(object):
"""docstring for SNSAPITutorial"""
def __init__(self):
super(SNSAPITutorial, self).__init__()
self.pointer = -1
self.sections = []
self.sections.append("""
Section 0. Introduction
This tutorial will present the basics of
SNSAPI to you. We'll walk you through
configuring, authorising, reading timeline,
updating status, replying to one status, etc.
To navigate this tutorial, you need:
>>> tut.next() # move to next section
>>> tut.prev() # move to previous section
Note that "print tut" is the shortcut
to move to the next section.
The tutorial will loop around after it hits
the last section.
""")
self.sections.append("""
Section 1. Help and Principles
Type "print helpdoc" whenever you forget commands.
Note that those commands are essentially Python
functions derived from SNSPocket class. You
can use the normal way to invoke them and seek
for online documentation.
e.g.
Type "list_channel()" to list the current
channels.
e.g.
Type "help(sp.list_channel)" to see the
detailed description of parameters.
""")
self.sections.append("""
Section 2. Create Your First Channel
Type:
>>> nc = new_channel()
>>> print nc
See the template we created for you. Now fill in
information using standard Python assignment.
e.g.
>>> nc["channel_name"] = "test_rss"
We subscribe the RSS feed of SNSAPI wiki pages.
Configure accordingly, and add this channel:
>>> nc["channel_name"] = "test_rss"
>>> nc["url"] = "https://github.com/hupili/snsapi/wiki.atom"
>>> nc["platform"] = "RSS"
>>> add_channel(nc)
You can use "list_channel()" to check it.
You can use "list_platform()" to see what are the currently
supported platforms.
""")
self.sections.append("""
Section 3. Read Your Timeline
Type:
>>> sl = home_timeline()
>>> print sl
You can read the news feeds of SNSAPI wiki pages now.
In order to expose the same interface as other platforms,
only a subset of the information is formatted. e.g.
publish date, author, title, and link.
The basic function of SNSAPI is to unify the interface.
You can expect to call home_timeline() on any other
platforms (most of them). The returned object is a list.
You can of course inspect it using "print sl[0]",
"print len(sl)".
""")
self.sections.append("""
Section 4. Load, Save Configuration
Try:
>>> save_config()
You can "quit()" and invoke this CLI again. Use
"load_config()" to recover the channels you've just
configured. To let this tutorial continue, we try to
clear channels and load them from file.
Try:
>>> list_channel()
>>> clear_channel()
>>> list_channel()
>>> load_config()
>>> list_channel()
You don't have problem figuring out what's going on
by looking at the console output.
""")
self.sections.append("""
Section 5. Configure one "Real" SNS (OSN)
The RSS channel just gives you a flavour of how SNSAPI
works. It requires the minimum operation. In this section,
we'll configure one Renren channel and update/reply
status using SNSAPI. You have to spend some time applying
for an app key.
See our wiki page if you haven't done so or you need
troubleshooting assistance:
https://github.com/hupili/snsapi/wiki/Apply-for-app-key
Try:
>>> clear_channel()
>>> nc = new_channel()
>>> nc["platform"] = "RenrenStatus"
>>> nc["app_secret"] = "YOU_APP_SECRET_KEY"
>>> nc["app_key"] = "YOU_APP_KEY"
>>> nc["channel_name"] = "test_renren"
>>> nc["auth_info"]["callback_url"] = "http://snsapi.sinaapp.com/auth.php"
>>> add_channel(nc)
>>> auth()
>>> sl = home_timeline(count = 5)
>>> print sl
In the auth stage, you will be prompt a browser for
authorization by default. After authorizing your own
App, you can copy the url which contains authorization
code to snscli console. If you use the above defaults,
we should be able to guide you through the process at
every step. Check wether you get 5 statuses from
your home timeline.
""")
self.sections.append("""
Section 6. Update and Reply on SNS
Try update your own status:
>>> update("t.....")
>>> sl = home_timeline(count = 5)
>>> print sl[0]
If the return value is "True", then we successfully updated
one status. We can get the status using home_timeline().
Check if this is the message you just post.
Now we reply to it:
>>> reply(sl[0].ID, "a reply")
Again, you'll see "True" on successful reply. You can
login the web portal of this SNS and check whether it
is successful.
""")
self.sections.append("""
Section 7. Cross Channel Operation
Let's do something advanced. First configure one OSN
channel as is done in the last two sections. Then
configure one RSS2RW channel. You can write feeds using
RSS2RW channel. Here's the basic settings:
>>> n["platform"] = "RSS2RW"
>>> n["channel_name"] = "output"
>>> n["url"] = "output.atom"
>>> add_channel(n)
>>> list_channel()
Let's read the statuses from OSN and write some of
them to an RSS2 feed:
>>> sl = home_timeline(5)
>>> print sl[0]
>>> print home_timeline(channel = "output")
>>> update(text = unicode(sl[0]), channel = "output")
>>> print home_timeline(channel = "output")
>>> update(text = unicode(sl[3]), channel = "output")
>>> print home_timeline(channel = "output")
Besides the console output, you can also check the
resuling "output.atom" file. It is a valid RSS file
so you can subscribe to it using RSS Readers. Note
how simple this task is! It's a totally different
thing from OSN, but you can use the same "update()"
method to put information there!
""")
self.sections.append("""
Section 8. Advanced Use Case
Congratulations! You have grasped all basics of SNSAPI.
Feeling interested? Um, let's look at one more complex
idea:
* Follow (being friends with) different users on
different platforms.
* Use SNSAPI to pull all the new information.
* Classifying, filtering, etc. Whatever you like.
* Output those valuable statuses to one single
RSS file.
* Subscribe to that feed alone! You can get all
information in just one place.
* Take a step further. You can use ifttt.com to
forward the RSS to your cell phone by SMS for free!
Think wild. We are standing on top of different platforms
(and there will definitely be more). Let's make all
the things to work for us.
""")
self.sections.append("""
Section 9. Programming Interface
Don't know Python?
It's absolutely OK!
We intend to use STDIN/STDOUT to communicate with
all other languages. (of course, Python programmers
will find it more convenient to use the class directly)
e.g.
echo -e 'load_config()\\nauth()\\nprint home_timeline(5)\\nquit()' | python -i snscli.py
You can use the above line to get home timeline from
bash. You can deal with it using grep, awk, etc. Same
to all other programming laguages: write command to
STDIN and read result from STDOUT. You may have noticed
that the console output is not clean. Writing logs to
a file will make it much better. Check out the next
and the last section for pointers.
""")
self.sections.append("""
Section 10. Closing Remarks
Here's a few pointers to proceed next:
* Check out our wiki for more advanced use cases.
* Check "snsapi/snsconf.py" for some hardcoded
but tunable configurations. (e.g. those of logging)
* Check "snsapi/app" for some sample apps.
* Look at the codes, write plugins, write Apps, etc.
Enjoy!
The next time you type "print tut", we'll start
all over again~
""")
def next(self):
self.pointer += 1
tut = self.sections[self.pointer % len(self.sections)]
console_output(tut)
def prev(self):
self.pointer -= 1
tut = self.sections[self.pointer % len(self.sections)]
console_output(tut)
def __str__(self):
self.pointer += 1
tut = self.sections[self.pointer % len(self.sections)]
return tut
tut = SNSAPITutorial()
#==== default initialization one may like ====
print helpdoc
load_config()
list_channel()
auth()