Merge lp:~tsyrus/pastebinit/pastebinthat into lp:pastebinit

Proposed by Terence Syrus
Status: Work in progress
Proposed branch: lp:~tsyrus/pastebinit/pastebinthat
Merge into: lp:pastebinit
Diff against target: 1419 lines (+639/-483)
21 files modified
pastebin.d/cxg.de.conf (+4/-7)
pastebin.d/dpaste.com.conf (+17/-0)
pastebin.d/fpaste.org.conf (+1/-1)
pastebin.d/lpaste.net.conf (+2/-3)
pastebin.d/p.defau.lt.conf (+2/-5)
pastebin.d/paste.debian.net.conf (+1/-1)
pastebin.d/paste.drizzle.org.conf (+6/-9)
pastebin.d/paste.kde.org.conf (+10/-14)
pastebin.d/paste.openstack.org.conf (+6/-9)
pastebin.d/paste.pound-python.org.conf (+1/-1)
pastebin.d/paste.ubuntu.com.conf (+1/-1)
pastebin.d/paste.ubuntu.org.cn.conf (+1/-1)
pastebin.d/paste2.org.conf (+1/-1)
pastebin.d/pastebin.com.conf (+4/-5)
pastebin.d/pastebin.mate-desktop.org.conf (+7/-9)
pastebin.d/pb.daviey.com.conf (+4/-5)
pastebin.d/slexy.org.conf (+2/-3)
pastebin.d/sprunge.us.conf (+3/-5)
pastebinit (+417/-398)
test.py (+135/-0)
test.sh (+14/-5)
To merge this branch: bzr merge lp:~tsyrus/pastebinit/pastebinthat
Reviewer Review Type Date Requested Status
Pastebinit Developers Pending
Review via email: mp+243250@code.launchpad.net

Description of the change

Complete overhaul of pastebinit:
* significantly cleaned up code for less coupling and more readability
* changed config to a more sensible structure:
** only posted parameters are in the format section now
** parameters that were previously hidden but listed in the format section now live in the pastebin section
* added unit tests
* merged in all branches from ~blueyed

To post a comment you must log in.
lp:~tsyrus/pastebinit/pastebinthat updated
216. By Terence Syrus <email address hidden>

added unit tests

217. By Terence Syrus <email address hidden>

removed unused method

218. By Terence Syrus <email address hidden>

removed debug

Revision history for this message
Stéphane Graber (stgraber) wrote :

Hi,

I'm sorry I didn't see this before, as you most likely figured out by now, I'm not very actively involved anymore as pastebinit pretty much just works for me and has done so for years.

I'm certainly happy with work to make it less crufty and better tested, unfortunately it looks like the bunch of changes I applied today makes this fail to apply.

Any chance you can rebase this on current pastebinit. I'll try to be faster to respond this time! :)

Unmerged revisions

218. By Terence Syrus <email address hidden>

removed debug

217. By Terence Syrus <email address hidden>

removed unused method

216. By Terence Syrus <email address hidden>

added unit tests

215. By Terence Syrus <email address hidden>

major overhaul: tests + cleanup

214. By Terence Syrus <email address hidden>

major cleanup
also, updated pastebin.mate-desktop.org.conf

213. By Terence Syrus <email address hidden>

merged changes from Daniel Hahler

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'pastebin.d/cxg.de.conf'
2--- pastebin.d/cxg.de.conf 2012-06-13 16:41:21 +0000
3+++ pastebin.d/cxg.de.conf 2014-12-02 02:23:09 +0000
4@@ -1,14 +1,11 @@
5 [pastebin]
6 basename = cxg.de
7-regexp = http://cxg.de
8+id_regexp = http://cxg.de
9+result_type = url
10+result_regexp = href="(http://cxg.de/.*)"
11+page = /paste.php
12
13 [format]
14 user = desc
15 content = pastetext
16 format = lang
17-page = page
18-regexp = regexp
19-
20-[defaults]
21-page = /paste.php
22-regexp = href="http://cxg.de/(.*)"
23
24=== added file 'pastebin.d/dpaste.com.conf'
25--- pastebin.d/dpaste.com.conf 1970-01-01 00:00:00 +0000
26+++ pastebin.d/dpaste.com.conf 2014-12-02 02:23:09 +0000
27@@ -0,0 +1,17 @@
28+[pastebin]
29+basename = dpaste.com
30+id_regexp = http://dpaste.com
31+page = /api/v1/
32+
33+[format]
34+user = poster
35+content = content
36+title = title
37+format = language
38+hold = hold
39+
40+[defaults]
41+# Empty means "Plain".
42+format =
43+# Keep it for 30 days after last access. Otherwise only for 7 days.
44+hold = on
45
46=== modified file 'pastebin.d/fpaste.org.conf'
47--- pastebin.d/fpaste.org.conf 2014-01-06 20:58:13 +0000
48+++ pastebin.d/fpaste.org.conf 2014-12-02 02:23:09 +0000
49@@ -1,6 +1,6 @@
50 [pastebin]
51 basename = fpaste.org
52-regexp = http://fpaste.org
53+id_regexp = http://fpaste.org
54
55 [format]
56 user = paste_user
57
58=== modified file 'pastebin.d/lpaste.net.conf'
59--- pastebin.d/lpaste.net.conf 2014-01-06 22:59:43 +0000
60+++ pastebin.d/lpaste.net.conf 2014-12-02 02:23:09 +0000
61@@ -1,6 +1,7 @@
62 [pastebin]
63 basename = lpaste.net
64-regexp = http://lpaste.net
65+id_regexp = http://lpaste.net
66+page = new
67
68 [format]
69 public = public
70@@ -10,10 +11,8 @@
71 channel = channel
72 content = paste
73 email = email
74-page = page
75
76 [defaults]
77-page = new
78 public = Public
79 channel =
80 email =
81
82=== modified file 'pastebin.d/p.defau.lt.conf'
83--- pastebin.d/p.defau.lt.conf 2012-06-13 16:41:21 +0000
84+++ pastebin.d/p.defau.lt.conf 2014-12-02 02:23:09 +0000
85@@ -1,10 +1,7 @@
86 [pastebin]
87 basename = p.defau.lt
88-regexp = http://p.defau.lt
89+id_regexp = http://p.defau.lt
90+page = /submit.php
91
92 [format]
93 content = code
94-page = page
95-
96-[defaults]
97-page = /submit.php
98
99=== modified file 'pastebin.d/paste.debian.net.conf'
100--- pastebin.d/paste.debian.net.conf 2012-06-13 16:41:21 +0000
101+++ pastebin.d/paste.debian.net.conf 2014-12-02 02:23:09 +0000
102@@ -1,6 +1,6 @@
103 [pastebin]
104 basename = paste.debian.net
105-regexp = http://paste.debian.net
106+id_regexp = https?://paste.debian.net
107
108 [format]
109 user = poster
110
111=== modified file 'pastebin.d/paste.drizzle.org.conf'
112--- pastebin.d/paste.drizzle.org.conf 2012-06-13 16:41:21 +0000
113+++ pastebin.d/paste.drizzle.org.conf 2014-12-02 02:23:09 +0000
114@@ -1,18 +1,15 @@
115 [pastebin]
116 basename = paste.drizzle.org
117-regexp = http://paste.drizzle.org
118+id_regexp = http://paste.drizzle.org
119+target_url = http://paste.drizzle.org/show/
120+result_type = id
121+result_regexp = \"data\": \"([^"]*)
122+post_format = json
123+page = /json/?method=pastes.newPaste
124
125 [format]
126 lang = language
127-page = page
128 content = code
129-post_format = post_format
130-regexp = regexp
131-target_url = target_url
132
133 [defaults]
134-page = /json/?method=pastes.newPaste
135-post_format = json
136 lang =
137-regexp = \"data\": \"([^"]*)
138-target_url = http://paste.drizzle.org/show/
139
140=== modified file 'pastebin.d/paste.kde.org.conf'
141--- pastebin.d/paste.kde.org.conf 2012-06-13 16:41:21 +0000
142+++ pastebin.d/paste.kde.org.conf 2014-12-02 02:23:09 +0000
143@@ -1,22 +1,18 @@
144 [pastebin]
145 basename = paste.kde.org
146-regexp = http://paste.kde.org
147+id_regexp = http://paste.kde.org
148+result_type = id
149+result_regexp = <id>(.*)</id>
150+page = /api/xml/create
151
152 [format]
153-user = paste_user
154-format = paste_lang
155-content = paste_data
156-password = paste_password
157-expire = paste_expire
158-private = paste_private
159-api = api_submit
160-mode = mode
161-regexp = regexp
162+format = language
163+content = data
164+expire = expire
165+private = private
166+title = title
167+password = password
168
169 [defaults]
170-private = 0
171 format = text
172 expire = 86400
173-api = 1
174-mode = xml
175-regexp = <id>(.*)</id>
176
177=== modified file 'pastebin.d/paste.openstack.org.conf'
178--- pastebin.d/paste.openstack.org.conf 2012-06-13 17:15:59 +0000
179+++ pastebin.d/paste.openstack.org.conf 2014-12-02 02:23:09 +0000
180@@ -1,18 +1,15 @@
181 [pastebin]
182 basename = paste.openstack.org
183-regexp = http://paste.openstack.org
184+id_regexp = http://paste.openstack.org
185+result_type = id
186+result_regexp = \"data\": \"([^"]*)
187+target_url = http://paste.openstack.org/show/
188+post_format = json
189+page = /json/?method=pastes.newPaste
190
191 [format]
192 lang = language
193-page = page
194 content = code
195-post_format = post_format
196-regexp = regexp
197-target_url = target_url
198
199 [defaults]
200-page = /json/?method=pastes.newPaste
201-post_format = json
202 lang =
203-regexp = \"data\": \"([^"]*)
204-target_url = http://paste.openstack.org/show/
205
206=== modified file 'pastebin.d/paste.pound-python.org.conf'
207--- pastebin.d/paste.pound-python.org.conf 2012-06-13 16:41:21 +0000
208+++ pastebin.d/paste.pound-python.org.conf 2014-12-02 02:23:09 +0000
209@@ -1,6 +1,6 @@
210 [pastebin]
211 basename = paste.pound-python.org
212-regexp = http://paste.pound-python.org
213+id_regexp = http://paste.pound-python.org
214
215 [format]
216 content = code
217
218=== modified file 'pastebin.d/paste.ubuntu.com.conf'
219--- pastebin.d/paste.ubuntu.com.conf 2012-06-13 16:41:21 +0000
220+++ pastebin.d/paste.ubuntu.com.conf 2014-12-02 02:23:09 +0000
221@@ -1,6 +1,6 @@
222 [pastebin]
223 basename = paste.ubuntu.com
224-regexp = http://paste.ubuntu.com
225+id_regexp = http://paste.ubuntu.com
226
227 [format]
228 user = poster
229
230=== modified file 'pastebin.d/paste.ubuntu.org.cn.conf'
231--- pastebin.d/paste.ubuntu.org.cn.conf 2012-06-13 16:41:21 +0000
232+++ pastebin.d/paste.ubuntu.org.cn.conf 2014-12-02 02:23:09 +0000
233@@ -1,6 +1,6 @@
234 [pastebin]
235 basename = paste.ubuntu.org.cn
236-regexp = http://paste.ubuntu.org.cn
237+id_regexp = http://paste.ubuntu.org.cn
238
239 [format]
240 user = poster
241
242=== modified file 'pastebin.d/paste2.org.conf'
243--- pastebin.d/paste2.org.conf 2014-01-06 23:16:01 +0000
244+++ pastebin.d/paste2.org.conf 2014-12-02 02:23:09 +0000
245@@ -1,6 +1,6 @@
246 [pastebin]
247 basename = paste2.org
248-regexp = http://paste2.org
249+id_regexp = http://paste2.org
250
251 [format]
252 title = description
253
254=== modified file 'pastebin.d/pastebin.com.conf'
255--- pastebin.d/pastebin.com.conf 2012-06-13 17:15:59 +0000
256+++ pastebin.d/pastebin.com.conf 2014-12-02 02:23:09 +0000
257@@ -1,6 +1,9 @@
258 [pastebin]
259 basename = pastebin.com
260-regexp = http://((([a-zA-Z0-9\-_\.]*)(pastebin\.com)))
261+id_regexp = http://((([a-zA-Z0-9\-_\.]*)(pastebin\.com)))
262+result_type = url
263+result_regexp = (.*)
264+page = /api/api_post.php
265
266 [format]
267 content = api_paste_code
268@@ -10,9 +13,7 @@
269 expiry = api_paste_expire_date
270 format = api_paste_format
271 email = api_paste_email
272-page = page
273 submit = submit
274-regexp = regexp
275 api_dev_key = api_dev_key
276 api_option = api_option
277
278@@ -25,5 +26,3 @@
279 email =
280 api_dev_key = 253ce2f0a45140ee0a44ca99aa492260
281 api_option = paste
282-page = /api/api_post.php
283-regexp = (.*)
284
285=== modified file 'pastebin.d/pastebin.mate-desktop.org.conf'
286--- pastebin.d/pastebin.mate-desktop.org.conf 2014-01-06 20:40:29 +0000
287+++ pastebin.d/pastebin.mate-desktop.org.conf 2014-12-02 02:23:09 +0000
288@@ -1,14 +1,12 @@
289 [pastebin]
290 basename = pastebin.mate-desktop.org
291-regexp = http://pastebin.mate-desktop.org
292+page = /api/json/create
293+id_regexp = http://pastebin.mate-desktop.org
294+result_type = id
295+result_regexp = "id": "([^"]*)"
296+post_format = json
297
298 [format]
299-content = text
300+content = data
301 user = name
302-format = lang
303-page = page
304-regexp = regexp
305-
306-[defaults]
307-page = /api/create
308-regexp = (.*)
309+format = language
310
311=== modified file 'pastebin.d/pb.daviey.com.conf'
312--- pastebin.d/pb.daviey.com.conf 2012-06-13 17:15:59 +0000
313+++ pastebin.d/pb.daviey.com.conf 2014-12-02 02:23:09 +0000
314@@ -1,16 +1,15 @@
315 [pastebin]
316 basename = pb.daviey.com
317-regexp = http://pb.daviey.com
318+id_regexp = http://pb.daviey.com
319+result_regexp = "/(.*/)".*
320+result_type = id
321+page = api/?_call=new
322
323 [format]
324 user = author
325 content = content
326-page = page
327 expire_options = expires
328 title = title
329-regexp = regexp
330
331 [defaults]
332-page = api/?_call=new
333-regexp = "/(.*/)".*
334 expire_options = 7889232
335
336=== modified file 'pastebin.d/slexy.org.conf'
337--- pastebin.d/slexy.org.conf 2012-06-13 17:15:59 +0000
338+++ pastebin.d/slexy.org.conf 2014-12-02 02:23:09 +0000
339@@ -1,12 +1,12 @@
340 [pastebin]
341 basename = slexy.org
342-regexp = http://slexy.org
343+id_regexp = http://slexy.org
344+page = /index.php/submit
345
346 [format]
347 user = author
348 content = raw_paste
349 title = desc
350-page = page
351 language = language
352 permissions = permissions
353 linenumbers = linenumbers
354@@ -16,7 +16,6 @@
355
356 [defaults]
357 submit = Submit Paste
358-page = /index.php/submit
359 language = text
360 permissions = 0
361 comment =
362
363=== modified file 'pastebin.d/sprunge.us.conf'
364--- pastebin.d/sprunge.us.conf 2012-06-13 16:41:21 +0000
365+++ pastebin.d/sprunge.us.conf 2014-12-02 02:23:09 +0000
366@@ -1,11 +1,9 @@
367 [pastebin]
368 basename = sprunge.us
369-regexp = http://sprunge.us
370+id_regexp = http://sprunge.us
371+result_regexp=http://sprunge.us/(.*)$
372+result_type = id
373
374 [format]
375 content = sprunge
376 format = lang
377-regexp = regexp
378-
379-[defaults]
380-regexp=http://sprunge.us/(.*)$
381
382=== modified file 'pastebinit'
383--- pastebinit 2014-01-18 04:51:35 +0000
384+++ pastebinit 2014-12-02 02:23:09 +0000
385@@ -4,7 +4,7 @@
386 # Author: Stéphane Graber <stgraber@ubuntu.com>
387 # Written by Stéphane Graber <stgraber@stgraber.org>
388 # Daniel Bartlett <dan@f-box.org>
389-# Last modification : Mon Jan 6 18:46:46 EST 2014
390+# Last modification : Mon Nov 24 15:07:45 EST 2014
391
392 # This program is free software; you can redistribute it and/or modify
393 # it under the terms of the GNU General Public License as published by
394@@ -23,224 +23,48 @@
395 from __future__ import print_function
396
397 import sys
398+import os
399+import re
400+import getopt
401+import gettext
402+import socket
403+import xml.dom.minidom
404+
405 if sys.version[0] == "2":
406- from ConfigParser import SafeConfigParser
407+ from ConfigParser import SafeConfigParser, NoOptionError, NoSectionError
408 from urllib import urlencode
409 from urllib import FancyURLopener
410 else:
411- from configparser import SafeConfigParser
412+ #SafeConfigParser is now a deprecated alias to ConfigParser
413+ from configparser import \
414+ ConfigParser as SafeConfigParser, NoOptionError, NoSectionError
415 from urllib.parse import urlencode
416 from urllib.request import FancyURLopener
417
418-# Set the default pastebin
419-defaultPB = "http://pastebin.com"
420
421-# Now try to override it with a distributor pastebin
422 try:
423- import lsb_release
424- release = lsb_release.get_distro_information()['ID'].lower()
425- if release == 'debian':
426- defaultPB = "http://paste.debian.net"
427- elif release == 'fedora':
428- defaultPB = "http://fpaste.org"
429- elif release == 'ubuntu':
430- defaultPB = "http://paste.ubuntu.com"
431+ import json
432 except ImportError:
433- pass
434-
435-try:
436- import getopt
437- import gettext
438- import os
439- import re
440- import socket
441- import xml.dom.minidom
442-
443- try:
444- import json
445- except ImportError:
446- json = None
447-
448- _ = gettext.gettext
449- gettext.textdomain("pastebinit")
450-
451- # Timeout after 5s
452- socket.setdefaulttimeout(5)
453-
454- # Version number to show in the usage
455- version = "1.4.1"
456- configfile = os.path.expanduser("~/.pastebinit.xml")
457-
458- # Custom urlopener to handle 401's
459- class pasteURLopener(FancyURLopener):
460- version = "Pastebinit v%s" % version
461-
462- def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
463- return None
464-
465- def preloadPastebins():
466- # Check several places for config files:
467- # - global config in /etc/pastebin.d
468- # - for source checkout, config in the checkout
469- # - user's overrides in ~/.pastebin.d
470- # Files found later override files found earlier.
471- pastebind = {}
472- for confdir in ['/usr/share/pastebin.d', '/etc/pastebin.d',
473- '/usr/local/etc/pastebin.d',
474- os.path.expanduser('~/.pastebin.d'),
475- os.path.join(
476- os.path.dirname(
477- os.path.realpath(__file__)), 'pastebin.d')]:
478- try:
479- confdirlist = os.listdir(confdir)
480- except OSError:
481- continue
482-
483- for fileitem in confdirlist:
484- if fileitem.startswith('.') or not fileitem.endswith('.conf'):
485- continue
486-
487- filename = os.path.join(confdir, fileitem)
488- instance = SafeConfigParser()
489- try:
490- instance.read(filename)
491- except UnicodeError:
492- continue
493-
494- if not instance.has_section('pastebin'):
495- print(_('%s: no section [pastebin]') % filename,
496- file=sys.stderr)
497- continue
498-
499- if not instance.has_option('pastebin', 'basename'):
500- print(_("%s: no 'basename' in [pastebin]") % filename,
501- file=sys.stderr)
502- continue
503-
504- pastebind[instance.get('pastebin', 'basename')] = instance
505- return pastebind
506-
507- # pastey.net obfuscates parent ids for replies. Rather than taking the
508- # post ID given as the parent ID, we must handle this by going to that
509- # post page and looking up what the invisible parent ID field will be
510- # set to for children.
511- def doParentFixup(website, paramname, parentid):
512- if parentid == "":
513- return ""
514- url_opener = pasteURLopener()
515- page = url_opener.open(website + '/' + parentid, None)
516- matches = re.split('<input.*?name="' + paramname + '".*?value="(.*?)"',
517- page.read())
518- if len(matches) <= 1 or re.match(parentid, matches[1]) is None:
519- # The obfuscated version didn't begin with the partial version,
520- # or unable to find the obfuscated version for some reason!
521- # Create a paste with no parent (should we throw, instead?)
522- return ""
523- return matches[1]
524-
525- #Return the parameters depending of the pastebin used
526- def getParameters(website, pastebind, content, user, jabberid, version,
527- format, parentpid, permatag, title, username,
528- password):
529- "Return the parameters array for the selected pastebin"
530- params = {}
531- for paste_name, paste_config in pastebind.items():
532- basename = paste_config.get('pastebin', 'basename')
533- if basename == website or paste_name == website:
534- website = "http://%s" % basename
535-
536- if re.search(paste_config.get('pastebin', 'regexp'), website):
537- if paste_config.has_option('pastebin', 'sizelimit'):
538- params['sizelimit'] = paste_config.get('pastebin',
539- 'sizelimit')
540-
541- for param in paste_config.options('format'):
542- paramname = paste_config.get('format', param)
543- if param == 'user':
544- params[paramname] = user
545- elif param == 'content':
546- params[paramname] = content
547- elif param == 'title':
548- params[paramname] = title
549- elif param == 'version':
550- params[paramname] = version
551- elif param == 'format':
552- params[paramname] = format
553- elif param == 'parentpid':
554- params[paramname] = doParentFixup(website, paramname,
555- parentpid)
556- elif param == 'permatag':
557- params[paramname] = permatag
558- elif param == 'username':
559- params[paramname] = username
560- elif param == 'password':
561- params[paramname] = password
562- elif param == 'jabberid':
563- params[paramname] = jabberid
564- else:
565- params[paramname] = paste_config.get('defaults', param)
566- if params:
567- return website, params
568- else:
569- print(_("Unknown website, please post a bugreport to request "
570- "this pastebin to be added (%s)") % website,
571- file=sys.stderr)
572- sys.exit(1)
573-
574- #XML Handling methods
575- def getText(nodelist):
576- rc = ""
577- for node in nodelist:
578- if node.nodeType == node.TEXT_NODE:
579- rc = rc + node.data
580- return rc
581-
582- def getNodes(nodes, title):
583- return nodes.getElementsByTagName(title)
584-
585- def getFirstNode(nodes, title):
586- return getNodes(nodes, title)[0]
587-
588- def getFirstNodeText(nodes, title):
589- return getText(getFirstNode(nodes, title).childNodes)
590-
591- # Display usage instructions
592- def Usage(fd=sys.stdout):
593- print("pastebinit v" + version, file=fd)
594- print(_("Reads on stdin for input or takes a list of filenames "
595- "as parameters"), file=fd)
596- print(_("Optional arguments (not supported by all pastebins):"),
597- file=fd)
598- print(_("\t-a <author:default is '%s'>") % user, file=fd)
599- print(_("\t-b <pastebin url:default is '%s'>") % website, file=fd)
600- print(_("\t-f <format of paste:default is '%s'>") % format, file=fd)
601- print(_("\t-h This help screen"), file=fd)
602- print(_("\t-i <input file>"), file=fd)
603- print(_("\t-l List all supported pastebins"), file=fd)
604- print(_("\t-j <jabberid for notifications:default is '%s'>") %
605- jabberid, file=fd)
606- print(_("\t-m <permatag for all versions of a post:default is blank>"),
607- file=fd)
608- print(_("\t-r <parent posts ID:defaults to none>"), file=fd)
609- print(_("\t-t <title of paste:default is blank>"), file=fd)
610- print(_("\t-u <username> -p <password>"), file=fd)
611- print(_("\t-v Print the version number"), file=fd)
612-
613- # Set defaults
614- website = defaultPB
615- user = os.environ.get('USER')
616- jabberid = ""
617- title = ""
618- permatag = ""
619- format = "text"
620- username = ""
621- password = ""
622- filenames = []
623- content = ""
624- parentpid = ""
625-
626- #Example configuration file string
627- configexample = """\
628+ json = None
629+
630+#Enables input redirection during tests
631+stdin = sys.stdin
632+stderr = sys.stderr
633+stdout = sys.stdout
634+
635+_ = gettext.gettext
636+gettext.textdomain("pastebinit")
637+
638+# Timeout after 5s
639+socket.setdefaulttimeout(5)
640+
641+# Version number to show in the usage
642+version = "1.4.1"
643+config_path = os.path.expanduser("~/.pastebinit.xml")
644+verbose = False
645+
646+#Example configuration file string
647+config_example = """\
648 <pastebinit>
649 <pastebin>http://paste.debian.net</pastebin>
650 <author>A pastebinit user</author>
651@@ -249,201 +73,396 @@
652 </pastebinit>
653 """
654
655- #Open configuration file if it exists
656- try:
657- f = open(configfile)
658- configtext = f.read()
659+
660+class PasteURLopener(FancyURLopener):
661+ """Custom urlopener to handle 401's"""
662+ version = "Pastebinit v%s" % version
663+
664+ def __init__(self, fmt=''):
665+ self.fmt = fmt
666+ FancyURLopener.__init__(self)
667+
668+ def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
669+ return None
670+
671+ def format_params(self, params):
672+ if self.fmt == 'json':
673+ if not json:
674+ print(_("Could not find any json library."), file=stderr)
675+ sys.exit(1)
676+ return json.dumps(params)
677+ else:
678+ return urlencode(params)
679+
680+ def make_request(self, url, params):
681+ post_params = self.format_params(params)
682+
683+ if self.fmt == 'json':
684+ self.addheader('Content-type', 'text/json')
685+
686+ if verbose:
687+ print("POSTing to: %s" % url, file=stderr)
688+ print("\nParams: %s" % str(post_params), file=stderr)
689+
690+ try:
691+ return self.open(url, post_params)
692+ except KeyboardInterrupt:
693+ print(_("KeyboardInterrupt caught."), file=stderr)
694+ sys.exit(1)
695+ except Exception as e:
696+ print(_("Failed to contact the server: %s") % e, file=stderr)
697+ sys.exit(1)
698+
699+
700+def get_default_pastebin():
701+ default = "http://pastebin.com"
702+ try:
703+ import lsb_release
704+ return {
705+ 'debian': "http://paste.debian.net",
706+ 'fedora': "http://fpaste.org",
707+ 'ubuntu': "http://paste.ubuntu.com",
708+ }[lsb_release.get_distro_information()['ID'].lower()]
709+ except KeyError:
710+ return default
711+ except ImportError:
712+ return default
713+
714+
715+def defaults():
716+ return {
717+ 'website': get_default_pastebin(),
718+ 'user': os.environ.get('USER'),
719+ 'format': "text",
720+ 'jabberid': "",
721+ 'title': "",
722+ 'permatag': "",
723+ 'username': "",
724+ 'password': "",
725+ 'parentpid': "",
726+ 'verbose': False,
727+ }
728+
729+
730+def usage(fd):
731+ print("pastebinit v" + version, file=fd)
732+ print(_("Reads on stdin for input or takes a list of filenames "
733+ "as parameters"), file=fd)
734+ print(_("Optional arguments (not supported by all pastebins):"), file=fd)
735+ print(_("\t-a <author:default is '%s'>") % defaults()['user'], file=fd)
736+ print(_("\t-b <pastebin url:default is '%s'>") % defaults()['website'],
737+ file=fd)
738+ print(_("\t-f <format of paste:default is '%s' "
739+ "(or from pastebin config)>") % defaults()['format'], file=fd)
740+ print(_("\t-h This help screen"), file=fd)
741+ print(_("\t-i <input file>"), file=fd)
742+ print(_("\t-l List all supported pastebins"), file=fd)
743+ print(_("\t-j <jabberid for notifications:default is '%s'>") %
744+ defaults()['jabberid'], file=fd)
745+ print(_("\t-m <permatag for all versions of a post:default is blank>"),
746+ file=fd)
747+ print(_("\t-r <parent posts ID:defaults to none>"), file=fd)
748+ print(_("\t-t <title of paste:default is blank>"), file=fd)
749+ print(_("\t-u <username> -p <password>"), file=fd)
750+ print(_("\t-v Print the version number"), file=fd)
751+ print(_("\t--verbose Verbose output to stderr"), file=fd)
752+
753+
754+def preloadPastebins():
755+ """
756+ Check several places for config files:
757+ - global config in /etc/pastebin.d
758+ - for source checkout, config in the checkout
759+ - user's overrides in ~/.pastebin.d
760+ Files found later override files found earlier.
761+ """
762+ pastebind = {}
763+ for confdir in ['/usr/share/pastebin.d',
764+ '/etc/pastebin.d',
765+ '/usr/local/etc/pastebin.d',
766+ os.path.expanduser('~/.pastebin.d'),
767+ os.path.join(
768+ os.path.dirname(os.path.realpath(__file__)),
769+ 'pastebin.d'),
770+ ]:
771+ try:
772+ confdirlist = [
773+ x for x in os.listdir(confdir)
774+ if x.endswith('.conf') and not x.startswith('.')
775+ ]
776+ except OSError:
777+ continue
778+
779+ for fileitem in confdirlist:
780+ filename = os.path.join(confdir, fileitem)
781+ parser = SafeConfigParser()
782+ try:
783+ parser.read(filename)
784+ except UnicodeError:
785+ print(_('%s: Unicode Error') % filename, file=stderr)
786+ continue
787+
788+ if not parser.has_section('pastebin'):
789+ print(_('%s: no section [pastebin]') % filename,
790+ file=stderr)
791+ continue
792+
793+ if not parser.has_option('pastebin', 'basename'):
794+ print(_("%s: no 'basename' in [pastebin]") % filename,
795+ file=stderr)
796+ continue
797+
798+ pastebind[parser.get('pastebin', 'basename')] = parser
799+ return pastebind
800+
801+
802+def doParentFixup(paramname, settings):
803+ """
804+ pastey.net obfuscates parent ids for replies. Rather than taking the
805+ post ID given as the parent ID, we must handle this by going to that
806+ post page and looking up what the invisible parent ID field will be
807+ set to for children.
808+ """
809+ website = settings['website']
810+ parentid = settings['parentid']
811+ if not parentid:
812+ return ""
813+ if not website.endswith("/"):
814+ website += "/"
815+ matches = re.split(
816+ '<input.*?name="' + paramname + '".*?value="(.*?)"',
817+ PasteURLopener(settings.get('post_format', '')).open(
818+ website + parentid.lstrip('/'), None).read()
819+ )
820+ if len(matches) <= 1 or re.match(parentid, matches[1]) is None:
821+ # The obfuscated version didn't begin with the partial version,
822+ # or unable to find the obfuscated version for some reason!
823+ # Create a paste with no parent (should we throw, instead?)
824+ return ""
825+ return matches[1]
826+
827+
828+def getPasteConfig(website):
829+ for paste_name, paste_config in preloadPastebins().items():
830+ basename = paste_config.get('pastebin', 'basename')
831+ if basename == website or paste_name == website:
832+ website = "http://%s" % basename
833+ if re.search(paste_config.get('pastebin', 'id_regexp'), website):
834+ if not website.endswith("/"):
835+ website += "/"
836+ return paste_config, website
837+
838+ print(_("Unknown website, please post a bugreport to request this "
839+ "pastebin to be added (%s)") % website,
840+ file=stderr)
841+ sys.exit(1)
842+
843+
844+def readPasteConfig(paste_config, settings):
845+ """Return the parameters array for the selected pastebin"""
846+
847+ for param in paste_config.options('pastebin'):
848+ settings[param] = paste_config.get('pastebin', param)
849+
850+ post_params = {}
851+ for param in paste_config.options('format'):
852+ paramname = paste_config.get('format', param)
853+
854+ if param == 'content':
855+ pass
856+ elif param == 'parentpid':
857+ post_params[paramname] = doParentFixup(paramname, settings)
858+ else:
859+ try:
860+ post_params[paramname] = paste_config.get('defaults', param)
861+ except NoOptionError:
862+ pass
863+ except NoSectionError:
864+ pass
865+
866+ try:
867+ post_params[paramname] = settings[param]
868+ except KeyError:
869+ pass
870+
871+ return post_params
872+
873+
874+def getText(parent_node):
875+ """Read the text from an XML node"""
876+ rc = ""
877+ for node in parent_node.childNodes:
878+ if node.nodeType == node.TEXT_NODE:
879+ rc += node.data
880+ else:
881+ rc += getText(node)
882+ return rc
883+
884+
885+def readFile(location, mode="r"):
886+ f = open(location, mode)
887+ try:
888+ return f.read()
889+ except KeyboardInterrupt:
890+ print(_("KeyboardInterrupt caught."), file=stderr)
891+ sys.exit(1)
892+ except:
893+ print(_("Unable to read from: %s") % location, file=stderr)
894+ sys.exit(1)
895+ finally:
896 f.close()
897- gotconfigxml = True
898+
899+
900+def readConfigFile(config_text):
901+ """Update settings from config XML"""
902+ try:
903+ settings = {}
904+ configxml = xml.dom.minidom.parseString(config_text)
905+ for xml_var, setting in (('pastebin', 'website'),
906+ ('author', 'user'),
907+ ('format', 'format'),
908+ ('jabberid', 'jabberid')):
909+ try:
910+ settings[setting] = getText(
911+ configxml.getElementsByTagName(xml_var)[0])
912+ except IndexError:
913+ pass
914+ return settings
915 except KeyboardInterrupt:
916- print(_("KeyboardInterrupt caught."), file=sys.stderr)
917+ print(_("KeyboardInterrupt caught."), file=stderr)
918 sys.exit(1)
919 except:
920- gotconfigxml = False
921-
922- #Parse configuration file
923- if gotconfigxml:
924+ print(_("Error parsing configuration file!"), file=stderr)
925+ print(_("Please ensure that your configuration file looks "
926+ "similar to the following:"), file=stderr)
927+ print(config_example, file=stderr)
928+ sys.exit(1)
929+
930+
931+def getOpts(args=sys.argv[1:]):
932+ try:
933+ optlist, arglist = getopt.getopt(
934+ args, 'hvli:f:b:a:r:j:t:m:u:p:', ('verbose',))
935+ except getopt.GetoptError as e:
936+ print(_("Invalid arguments: %s!" % e) + "\n", file=stderr)
937+ usage(stderr)
938+ sys.exit(1)
939+ opts = dict(optlist)
940+ opts['-i'] = [opt[1] for opt in optlist if opt[0] == "-i"] + arglist
941+ return opts
942+
943+
944+def readOptions(opts):
945+ settings = {}
946+
947+ # Die if support information is requested
948+ if "-h" in opts:
949+ usage(stdout)
950+ sys.exit(0)
951+ if "-v" in opts:
952+ print("pastebinit v" + version, file=stdout)
953+ sys.exit(0)
954+ if "-l" in opts:
955+ print(_("Supported pastebins:"), file=stdout)
956+ for pastebin in sorted(preloadPastebins()):
957+ print("- %s" % pastebin, file=stdout)
958+ sys.exit(0)
959+
960+ # Configure the environment
961+ def setFromOpt(opt, label):
962 try:
963- configxml = xml.dom.minidom.parseString(configtext)
964- for variable, key in (('pastebin', 'website'), ('author', 'user'),
965- ('format', 'format'),
966- ('jabberid', 'jabberid')):
967- try:
968- value = getFirstNodeText(configxml, variable)
969- vars()[key] = value
970- except:
971- pass
972- except KeyboardInterrupt:
973- print(_("KeyboardInterrupt caught."), file=sys.stderr)
974- sys.exit(1)
975- except:
976- print(_("Error parsing configuration file!"), file=sys.stderr)
977- print(_("Please ensure that your configuration file looks "
978- "similar to the following:"), file=sys.stderr)
979- print(configexample, file=sys.stderr)
980- sys.exit(1)
981-
982- # Get options
983+ settings[label] = opts[opt]
984+ except KeyError:
985+ pass
986+
987+ setFromOpt('-b', 'website')
988+ setFromOpt('-a', 'user')
989+ setFromOpt('-f', 'format')
990+ setFromOpt('-j', 'jabberid')
991+ setFromOpt('-t', 'title')
992+ setFromOpt('-m', 'permatag')
993+ setFromOpt('-u', 'username')
994+ setFromOpt('-p', 'password')
995+ setFromOpt('-r', 'parentpid')
996+ settings['verbose'] = "--verbose" in opts
997+
998+ settings['contents'] = [readFile(fname, "rb") for fname in opts['-i']]
999+ if not settings['contents']:
1000+ settings['contents'].append(stdin.read())
1001+ return settings
1002+
1003+
1004+def readPageURL(page, settings):
1005+ website = settings['website']
1006+ result_type = settings.get('result_type', None)
1007 try:
1008- optlist, arglist = getopt.getopt(sys.argv[1:],
1009- 'hvli:f:b:a:r:j:t:m:u:p:')
1010- except KeyboardInterrupt:
1011- print(_("KeyboardInterrupt caught."), file=sys.stderr)
1012- sys.exit(1)
1013- except getopt.GetoptError:
1014- print(_("Invalid arguments!\n"), file=sys.stderr)
1015- Usage(sys.stderr)
1016- sys.exit(1)
1017-
1018- # Get the config
1019- pastebind = preloadPastebins()
1020-
1021- # Iterate through options
1022- for opt in optlist:
1023- if opt[0] == "-h":
1024- Usage()
1025- sys.exit(0)
1026- if opt[0] == "-i":
1027- filenames.append(opt[1])
1028- elif opt[0] == "-f":
1029- format = opt[1]
1030- elif opt[0] == "-b":
1031- website = opt[1]
1032- elif opt[0] == "-a":
1033- user = opt[1]
1034- elif opt[0] == "-r":
1035- parentpid = opt[1]
1036- elif opt[0] == "-j":
1037- jabberid = opt[1]
1038- elif opt[0] == "-l":
1039- print(_("Supported pastebins:"))
1040- for pastebin in sorted(pastebind):
1041- print("- %s" % pastebin)
1042- sys.exit(0)
1043- elif opt[0] == "-t":
1044- title = opt[1]
1045- elif opt[0] == "-m":
1046- permatag = opt[1]
1047- elif opt[0] == "-u":
1048- username = opt[1]
1049- elif opt[0] == "-p":
1050- password = opt[1]
1051- elif opt[0] == "-v":
1052- print("pastebinit v" + version)
1053- sys.exit(0)
1054-
1055- filenames += arglist
1056-
1057- if not filenames:
1058- filenames.append("-")
1059-
1060- contents = []
1061- for filename in filenames:
1062- # If - is specified as a filename read from stdin
1063- # otherwise load the specified files.
1064- if filename == "-":
1065- content = sys.stdin.read()
1066+ # Check if we have to apply a regexp
1067+ page_url = ""
1068+ if result_type:
1069+ result = page.read().decode('utf-8')
1070+ result_regex = settings.get('result_regexp', None)
1071+ if result_regex:
1072+ result = re.split(result_regex, result)[1]
1073+
1074+ if result_type == 'url':
1075+ page_url = result.strip()
1076+ elif result_type == 'id':
1077+ page_url = settings.get('target_url', website) + result.strip()
1078+ else:
1079+ raise ValueError(_("Unsupported result_type: %s" % result_type))
1080 else:
1081- try:
1082- with open(filename, "rb") as fd:
1083- content = fd.read()
1084- except KeyboardInterrupt:
1085- print(_("KeyboardInterrupt caught."), file=sys.stderr)
1086- sys.exit(1)
1087- except:
1088- print(_("Unable to read from: %s") % filename, file=sys.stderr)
1089- sys.exit(1)
1090-
1091+ page_url = page.url
1092+
1093+ # You may have posted to https:, but were given an http: url
1094+ if website.startswith('https:'):
1095+ page_url = page_url.replace('http:', 'https:')
1096+ return page_url
1097+
1098+ except KeyboardInterrupt:
1099+ print(_("KeyboardInterrupt caught."), file=stderr)
1100+ sys.exit(1)
1101+ except:
1102+ print(_("Unable to read or parse the result page, it could be a "
1103+ "server timeout or a change server side, "
1104+ "try with another pastebin."), file=stderr)
1105+ sys.exit(1)
1106+
1107+
1108+def validateContents(settings):
1109+ """Check for invalid contents"""
1110+ for content in settings['contents']:
1111 if not content:
1112 print(_("You are trying to send an empty document, exiting."),
1113- file=sys.stderr)
1114- sys.exit(1)
1115-
1116- contents.append(content)
1117-
1118- for content in contents:
1119- # Get the parameter array
1120- website, params = getParameters(website, pastebind, content, user,
1121- jabberid, version, format, parentpid,
1122- permatag, title, username, password)
1123-
1124- if not website.endswith("/"):
1125- website += "/"
1126-
1127- if "sizelimit" in params:
1128- if len(content) > int(params['sizelimit']):
1129- print(_("The content you are trying to send exceeds "
1130- "the pastebin's size limit."), file=sys.stderr)
1131- sys.exit(1)
1132- else:
1133- del params['sizelimit']
1134-
1135- reLink = None
1136- tmp_page = ""
1137- if "page" in params:
1138- website += params['page']
1139- tmp_page = params['page']
1140- del params["page"]
1141- if "regexp" in params:
1142- reLink = params['regexp']
1143- del params["regexp"]
1144- if "target_url" in params:
1145- target_url = params["target_url"]
1146- del params["target_url"]
1147- else:
1148- target_url = None
1149- if 'post_format' in params:
1150- post_format = params['post_format']
1151- del params['post_format']
1152- else:
1153- post_format = 'standard'
1154-
1155- url_opener = pasteURLopener()
1156-
1157- if post_format == 'json':
1158- if json:
1159- params = json.dumps(params)
1160- url_opener.addheader('Content-type', 'text/json')
1161- else:
1162- print(_("Could not find any json library."), file=sys.stderr)
1163- sys.exit(1)
1164- else:
1165- # Convert to a format usable with the HTML POST
1166- params = urlencode(params)
1167-
1168- # Send the informations and be redirected to the final page
1169- try:
1170- page = url_opener.open(website, params)
1171- except Exception as e:
1172- print(_("Failed to contact the server: %s") % e, file=sys.stderr)
1173- sys.exit(1)
1174-
1175- try:
1176- # Check if we have to apply a regexp
1177- if reLink:
1178- if target_url:
1179- website = target_url
1180- else:
1181- website = website.replace(tmp_page, "")
1182-
1183- if reLink == '(.*)':
1184- print(page.read().decode('utf-8').strip())
1185- else:
1186- # Print the result of the regexp
1187- print(website + re.split(reLink,
1188- page.read().decode('utf-8'))[1])
1189- else:
1190- # Get the final page and show the url
1191- print(page.url)
1192- except KeyboardInterrupt:
1193- print(_("KeyboardInterrupt caught."), file=sys.stderr)
1194- sys.exit(1)
1195- except:
1196- print(_("Unable to read or parse the result page, it could be a "
1197- "server timeout or a change server side, "
1198- "try with another pastebin."), file=sys.stderr)
1199- sys.exit(1)
1200-
1201-except KeyboardInterrupt:
1202- print(_("KeyboardInterrupt caught."), file=sys.stderr)
1203- sys.exit(1)
1204+ file=stderr)
1205+ sys.exit(1)
1206+
1207+ if len(content) > int(settings.get('sizelimit', sys.maxsize)):
1208+ print(_("The content you are trying to send exceeds "
1209+ "the pastebin's size limit."), file=stderr)
1210+ sys.exit(1)
1211+
1212+
1213+def main():
1214+ try:
1215+ settings = defaults()
1216+ settings.update(readConfigFile(readFile(config_path)))
1217+ settings.update(readOptions(getOpts()))
1218+ verbose = settings['verbose']
1219+
1220+ paste_config, settings['website'] = getPasteConfig(settings['website'])
1221+ params = readPasteConfig(paste_config, settings)
1222+
1223+ validateContents(settings)
1224+ opener = PasteURLopener(settings.get('post_format', ''))
1225+
1226+ url = settings['website'] + settings.get('page', '').lstrip("/")
1227+ for content in settings['contents']:
1228+ params[paste_config.get('format', 'content')] = content
1229+ page = opener.make_request(url, params)
1230+ print(readPageURL(page, settings), file=stdout)
1231+ except KeyboardInterrupt:
1232+ print(_("KeyboardInterrupt caught."), file=stderr)
1233+ sys.exit(1)
1234+
1235+if __name__ == '__main__':
1236+ main()
1237\ No newline at end of file
1238
1239=== added symlink 'pastebinit.py'
1240=== target is u'pastebinit'
1241=== added file 'test.py'
1242--- test.py 1970-01-01 00:00:00 +0000
1243+++ test.py 2014-12-02 02:23:09 +0000
1244@@ -0,0 +1,135 @@
1245+import unittest
1246+import pastebinit
1247+try:
1248+ from StringIO import StringIO
1249+except ImportError:
1250+ from io import StringIO
1251+
1252+pastebinit.stdin = StringIO('')
1253+pastebinit.stdout = StringIO('')
1254+pastebinit.stderr = StringIO('')
1255+
1256+
1257+class ConfigXMLTests(unittest.TestCase):
1258+
1259+ def test_config_xml_parse(self):
1260+ xml = """\
1261+ <pastebinit>
1262+ <pastebin>http://paste.debian.net</pastebin>
1263+ <author>A pastebinit user</author>
1264+ <jabberid>nobody@nowhere.org</jabberid>
1265+ <format>text</format>
1266+ </pastebinit>
1267+ """
1268+ out = {
1269+ 'website': u'http://paste.debian.net',
1270+ 'user': u'A pastebinit user',
1271+ 'jabberid': u'nobody@nowhere.org',
1272+ 'format': u'text',
1273+ }
1274+ assert pastebinit.readConfigFile(xml) == out, 'readConfigFile failed'
1275+
1276+ def test_config_xml_parse_missing(self):
1277+ xml = """\
1278+ <pastebinit>
1279+ <author>A pastebinit user</author>
1280+ <jabberid>nobody@nowhere.org</jabberid>
1281+ <format>text</format>
1282+ </pastebinit>
1283+ """
1284+ out = {
1285+ 'user': u'A pastebinit user',
1286+ 'jabberid': u'nobody@nowhere.org',
1287+ 'format': u'text',
1288+ }
1289+ assert pastebinit.readConfigFile(xml) == out, 'readConfigFile failed'
1290+
1291+ def test_config_xml_parse_additional(self):
1292+ xml = """\
1293+ <pastebinit>
1294+ <author>A pastebinit user</author>
1295+ <jabberid>nobody@nowhere.org</jabberid>
1296+ <format>text</format>
1297+ <test>nonsense</test>
1298+ </pastebinit>
1299+ """
1300+ out = {
1301+ 'user': u'A pastebinit user',
1302+ 'jabberid': u'nobody@nowhere.org',
1303+ 'format': u'text',
1304+ }
1305+ assert pastebinit.readConfigFile(xml) == out, 'readConfigFile failed'
1306+
1307+ def test_config_xml_parse_invalid(self):
1308+ try:
1309+ pastebinit.readConfigFile("invalid")
1310+ assert False, "Invalid file was parsed without error."
1311+ except SystemExit:
1312+ pass
1313+
1314+
1315+class GetOptsTests(unittest.TestCase):
1316+
1317+ def _check_arg(self, argname, settingname):
1318+ settings = pastebinit.readOptions(pastebinit.getOpts([argname, 'test']))
1319+ assert settings[settingname] == 'test', "Failed to read " + argname
1320+
1321+ def test_help(self):
1322+ try:
1323+ pastebinit.readOptions(['-h'])
1324+ assert False, "Failed to quit after help option"
1325+ except SystemExit:
1326+ pass
1327+
1328+ def test_list(self):
1329+ try:
1330+ pastebinit.readOptions(['-l'])
1331+ assert False, "Failed to quit after list option"
1332+ except SystemExit:
1333+ pass
1334+
1335+ def test_version(self):
1336+ try:
1337+ pastebinit.readOptions(['-v'])
1338+ assert False, "Failed to quit after version option"
1339+ except SystemExit:
1340+ pass
1341+
1342+ def test_website(self):
1343+ self._check_arg('-b', 'website')
1344+
1345+ def test_user(self):
1346+ self._check_arg('-a', 'user')
1347+
1348+ def test_format(self):
1349+ self._check_arg('-f', 'format')
1350+
1351+ def test_jabberid(self):
1352+ self._check_arg('-j', 'jabberid')
1353+
1354+ def test_title(self):
1355+ self._check_arg('-t', 'title')
1356+
1357+ def test_permatag(self):
1358+ self._check_arg('-m', 'permatag')
1359+
1360+ def test_username(self):
1361+ self._check_arg('-u', 'username')
1362+
1363+ def test_password(self):
1364+ self._check_arg('-p', 'password')
1365+
1366+ def test_parentpid(self):
1367+ self._check_arg('-r', 'parentpid')
1368+
1369+ def test_filenames(self):
1370+ opts = pastebinit.getOpts(['-i', 'testa',
1371+ '-i', 'testb',
1372+ '-i', 'testc',
1373+ ])
1374+ assert opts['-i'] == [
1375+ 'testa','testb','testc'], "Failed to read filenames"
1376+
1377+
1378+if __name__ == "__main__":
1379+ unittest.main()
1380
1381=== modified file 'test.sh'
1382--- test.sh 2014-01-06 23:23:28 +0000
1383+++ test.sh 2014-12-02 02:23:09 +0000
1384@@ -1,11 +1,16 @@
1385 #!/bin/sh
1386-teststring="blah blah blah"
1387+#paste.debian.net needs 3 lines
1388+teststring="""\
1389+test from pastebinit
1390+test from pastebinit
1391+test from pastebinit
1392+"""
1393
1394 for interpreter in python python3; do
1395- for pastebin in $($interpreter pastebinit -l | egrep "^-" | sed "s/^- //g")
1396+ for pastebin in $(ls pastebin.d/*.conf | sed 's~^pastebin.d/\(.*\)\.conf$~\1~')
1397 do
1398 echo "Trying http://$pastebin ($interpreter)"
1399- URL=$(echo "$teststring\n$teststring\n$teststring" | $interpreter pastebinit -b http://$pastebin)
1400+ URL=$(echo teststring | $interpreter ./pastebinit.py -b http://$pastebin)
1401
1402 if [ "$pastebin" = "paste.ubuntu.org.cn" ]; then
1403 out=$(wget -O - -q "$URL" | gzip -d | grep "$teststring")
1404@@ -14,9 +19,13 @@
1405 fi
1406
1407 if [ -n "$out" ]; then
1408- echo "PASS: http://$pastebin ($URL) ($interpreter)"
1409+ echo "PASS: http://$pastebin"
1410+ echo " ($URL)"
1411+ echo " ($interpreter)"
1412 else
1413- echo "FAIL: http://$pastebin ($URL) ($interpreter)"
1414+ echo "FAIL: http://$pastebin"
1415+ echo " ($URL)"
1416+ echo " ($interpreter)"
1417 fi
1418 echo ""
1419 done

Subscribers

People subscribed via source and target branches

to all changes: