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
=== modified file 'pastebin.d/cxg.de.conf'
--- pastebin.d/cxg.de.conf 2012-06-13 16:41:21 +0000
+++ pastebin.d/cxg.de.conf 2014-12-02 02:23:09 +0000
@@ -1,14 +1,11 @@
1[pastebin]1[pastebin]
2basename = cxg.de2basename = cxg.de
3regexp = http://cxg.de3id_regexp = http://cxg.de
4result_type = url
5result_regexp = href="(http://cxg.de/.*)"
6page = /paste.php
47
5[format]8[format]
6user = desc9user = desc
7content = pastetext10content = pastetext
8format = lang11format = lang
9page = page
10regexp = regexp
11
12[defaults]
13page = /paste.php
14regexp = href="http://cxg.de/(.*)"
1512
=== added file 'pastebin.d/dpaste.com.conf'
--- pastebin.d/dpaste.com.conf 1970-01-01 00:00:00 +0000
+++ pastebin.d/dpaste.com.conf 2014-12-02 02:23:09 +0000
@@ -0,0 +1,17 @@
1[pastebin]
2basename = dpaste.com
3id_regexp = http://dpaste.com
4page = /api/v1/
5
6[format]
7user = poster
8content = content
9title = title
10format = language
11hold = hold
12
13[defaults]
14# Empty means "Plain".
15format =
16# Keep it for 30 days after last access. Otherwise only for 7 days.
17hold = on
018
=== modified file 'pastebin.d/fpaste.org.conf'
--- pastebin.d/fpaste.org.conf 2014-01-06 20:58:13 +0000
+++ pastebin.d/fpaste.org.conf 2014-12-02 02:23:09 +0000
@@ -1,6 +1,6 @@
1[pastebin]1[pastebin]
2basename = fpaste.org2basename = fpaste.org
3regexp = http://fpaste.org3id_regexp = http://fpaste.org
44
5[format]5[format]
6user = paste_user6user = paste_user
77
=== modified file 'pastebin.d/lpaste.net.conf'
--- pastebin.d/lpaste.net.conf 2014-01-06 22:59:43 +0000
+++ pastebin.d/lpaste.net.conf 2014-12-02 02:23:09 +0000
@@ -1,6 +1,7 @@
1[pastebin]1[pastebin]
2basename = lpaste.net2basename = lpaste.net
3regexp = http://lpaste.net3id_regexp = http://lpaste.net
4page = new
45
5[format]6[format]
6public = public7public = public
@@ -10,10 +11,8 @@
10channel = channel11channel = channel
11content = paste12content = paste
12email = email13email = email
13page = page
1414
15[defaults]15[defaults]
16page = new
17public = Public16public = Public
18channel =17channel =
19email =18email =
2019
=== modified file 'pastebin.d/p.defau.lt.conf'
--- pastebin.d/p.defau.lt.conf 2012-06-13 16:41:21 +0000
+++ pastebin.d/p.defau.lt.conf 2014-12-02 02:23:09 +0000
@@ -1,10 +1,7 @@
1[pastebin]1[pastebin]
2basename = p.defau.lt2basename = p.defau.lt
3regexp = http://p.defau.lt3id_regexp = http://p.defau.lt
4page = /submit.php
45
5[format]6[format]
6content = code7content = code
7page = page
8
9[defaults]
10page = /submit.php
118
=== modified file 'pastebin.d/paste.debian.net.conf'
--- pastebin.d/paste.debian.net.conf 2012-06-13 16:41:21 +0000
+++ pastebin.d/paste.debian.net.conf 2014-12-02 02:23:09 +0000
@@ -1,6 +1,6 @@
1[pastebin]1[pastebin]
2basename = paste.debian.net2basename = paste.debian.net
3regexp = http://paste.debian.net3id_regexp = https?://paste.debian.net
44
5[format]5[format]
6user = poster6user = poster
77
=== modified file 'pastebin.d/paste.drizzle.org.conf'
--- pastebin.d/paste.drizzle.org.conf 2012-06-13 16:41:21 +0000
+++ pastebin.d/paste.drizzle.org.conf 2014-12-02 02:23:09 +0000
@@ -1,18 +1,15 @@
1[pastebin]1[pastebin]
2basename = paste.drizzle.org2basename = paste.drizzle.org
3regexp = http://paste.drizzle.org3id_regexp = http://paste.drizzle.org
4target_url = http://paste.drizzle.org/show/
5result_type = id
6result_regexp = \"data\": \"([^"]*)
7post_format = json
8page = /json/?method=pastes.newPaste
49
5[format]10[format]
6lang = language11lang = language
7page = page
8content = code12content = code
9post_format = post_format
10regexp = regexp
11target_url = target_url
1213
13[defaults]14[defaults]
14page = /json/?method=pastes.newPaste
15post_format = json
16lang =15lang =
17regexp = \"data\": \"([^"]*)
18target_url = http://paste.drizzle.org/show/
1916
=== modified file 'pastebin.d/paste.kde.org.conf'
--- pastebin.d/paste.kde.org.conf 2012-06-13 16:41:21 +0000
+++ pastebin.d/paste.kde.org.conf 2014-12-02 02:23:09 +0000
@@ -1,22 +1,18 @@
1[pastebin]1[pastebin]
2basename = paste.kde.org2basename = paste.kde.org
3regexp = http://paste.kde.org3id_regexp = http://paste.kde.org
4result_type = id
5result_regexp = <id>(.*)</id>
6page = /api/xml/create
47
5[format]8[format]
6user = paste_user9format = language
7format = paste_lang10content = data
8content = paste_data11expire = expire
9password = paste_password12private = private
10expire = paste_expire13title = title
11private = paste_private14password = password
12api = api_submit
13mode = mode
14regexp = regexp
1515
16[defaults]16[defaults]
17private = 0
18format = text17format = text
19expire = 8640018expire = 86400
20api = 1
21mode = xml
22regexp = <id>(.*)</id>
2319
=== modified file 'pastebin.d/paste.openstack.org.conf'
--- pastebin.d/paste.openstack.org.conf 2012-06-13 17:15:59 +0000
+++ pastebin.d/paste.openstack.org.conf 2014-12-02 02:23:09 +0000
@@ -1,18 +1,15 @@
1[pastebin]1[pastebin]
2basename = paste.openstack.org2basename = paste.openstack.org
3regexp = http://paste.openstack.org3id_regexp = http://paste.openstack.org
4result_type = id
5result_regexp = \"data\": \"([^"]*)
6target_url = http://paste.openstack.org/show/
7post_format = json
8page = /json/?method=pastes.newPaste
49
5[format]10[format]
6lang = language11lang = language
7page = page
8content = code12content = code
9post_format = post_format
10regexp = regexp
11target_url = target_url
1213
13[defaults]14[defaults]
14page = /json/?method=pastes.newPaste
15post_format = json
16lang =15lang =
17regexp = \"data\": \"([^"]*)
18target_url = http://paste.openstack.org/show/
1916
=== modified file 'pastebin.d/paste.pound-python.org.conf'
--- pastebin.d/paste.pound-python.org.conf 2012-06-13 16:41:21 +0000
+++ pastebin.d/paste.pound-python.org.conf 2014-12-02 02:23:09 +0000
@@ -1,6 +1,6 @@
1[pastebin]1[pastebin]
2basename = paste.pound-python.org2basename = paste.pound-python.org
3regexp = http://paste.pound-python.org3id_regexp = http://paste.pound-python.org
44
5[format]5[format]
6content = code6content = code
77
=== modified file 'pastebin.d/paste.ubuntu.com.conf'
--- pastebin.d/paste.ubuntu.com.conf 2012-06-13 16:41:21 +0000
+++ pastebin.d/paste.ubuntu.com.conf 2014-12-02 02:23:09 +0000
@@ -1,6 +1,6 @@
1[pastebin]1[pastebin]
2basename = paste.ubuntu.com2basename = paste.ubuntu.com
3regexp = http://paste.ubuntu.com3id_regexp = http://paste.ubuntu.com
44
5[format]5[format]
6user = poster6user = poster
77
=== modified file 'pastebin.d/paste.ubuntu.org.cn.conf'
--- pastebin.d/paste.ubuntu.org.cn.conf 2012-06-13 16:41:21 +0000
+++ pastebin.d/paste.ubuntu.org.cn.conf 2014-12-02 02:23:09 +0000
@@ -1,6 +1,6 @@
1[pastebin]1[pastebin]
2basename = paste.ubuntu.org.cn2basename = paste.ubuntu.org.cn
3regexp = http://paste.ubuntu.org.cn3id_regexp = http://paste.ubuntu.org.cn
44
5[format]5[format]
6user = poster6user = poster
77
=== modified file 'pastebin.d/paste2.org.conf'
--- pastebin.d/paste2.org.conf 2014-01-06 23:16:01 +0000
+++ pastebin.d/paste2.org.conf 2014-12-02 02:23:09 +0000
@@ -1,6 +1,6 @@
1[pastebin]1[pastebin]
2basename = paste2.org2basename = paste2.org
3regexp = http://paste2.org3id_regexp = http://paste2.org
44
5[format]5[format]
6title = description6title = description
77
=== modified file 'pastebin.d/pastebin.com.conf'
--- pastebin.d/pastebin.com.conf 2012-06-13 17:15:59 +0000
+++ pastebin.d/pastebin.com.conf 2014-12-02 02:23:09 +0000
@@ -1,6 +1,9 @@
1[pastebin]1[pastebin]
2basename = pastebin.com2basename = pastebin.com
3regexp = http://((([a-zA-Z0-9\-_\.]*)(pastebin\.com)))3id_regexp = http://((([a-zA-Z0-9\-_\.]*)(pastebin\.com)))
4result_type = url
5result_regexp = (.*)
6page = /api/api_post.php
47
5[format]8[format]
6content = api_paste_code9content = api_paste_code
@@ -10,9 +13,7 @@
10expiry = api_paste_expire_date13expiry = api_paste_expire_date
11format = api_paste_format14format = api_paste_format
12email = api_paste_email15email = api_paste_email
13page = page
14submit = submit16submit = submit
15regexp = regexp
16api_dev_key = api_dev_key17api_dev_key = api_dev_key
17api_option = api_option18api_option = api_option
1819
@@ -25,5 +26,3 @@
25email =26email =
26api_dev_key = 253ce2f0a45140ee0a44ca99aa49226027api_dev_key = 253ce2f0a45140ee0a44ca99aa492260
27api_option = paste28api_option = paste
28page = /api/api_post.php
29regexp = (.*)
3029
=== modified file 'pastebin.d/pastebin.mate-desktop.org.conf'
--- pastebin.d/pastebin.mate-desktop.org.conf 2014-01-06 20:40:29 +0000
+++ pastebin.d/pastebin.mate-desktop.org.conf 2014-12-02 02:23:09 +0000
@@ -1,14 +1,12 @@
1[pastebin]1[pastebin]
2basename = pastebin.mate-desktop.org2basename = pastebin.mate-desktop.org
3regexp = http://pastebin.mate-desktop.org3page = /api/json/create
4id_regexp = http://pastebin.mate-desktop.org
5result_type = id
6result_regexp = "id": "([^"]*)"
7post_format = json
48
5[format]9[format]
6content = text10content = data
7user = name11user = name
8format = lang12format = language
9page = page
10regexp = regexp
11
12[defaults]
13page = /api/create
14regexp = (.*)
1513
=== modified file 'pastebin.d/pb.daviey.com.conf'
--- pastebin.d/pb.daviey.com.conf 2012-06-13 17:15:59 +0000
+++ pastebin.d/pb.daviey.com.conf 2014-12-02 02:23:09 +0000
@@ -1,16 +1,15 @@
1[pastebin]1[pastebin]
2basename = pb.daviey.com2basename = pb.daviey.com
3regexp = http://pb.daviey.com3id_regexp = http://pb.daviey.com
4result_regexp = "/(.*/)".*
5result_type = id
6page = api/?_call=new
47
5[format]8[format]
6user = author9user = author
7content = content10content = content
8page = page
9expire_options = expires11expire_options = expires
10title = title12title = title
11regexp = regexp
1213
13[defaults]14[defaults]
14page = api/?_call=new
15regexp = "/(.*/)".*
16expire_options = 788923215expire_options = 7889232
1716
=== modified file 'pastebin.d/slexy.org.conf'
--- pastebin.d/slexy.org.conf 2012-06-13 17:15:59 +0000
+++ pastebin.d/slexy.org.conf 2014-12-02 02:23:09 +0000
@@ -1,12 +1,12 @@
1[pastebin]1[pastebin]
2basename = slexy.org2basename = slexy.org
3regexp = http://slexy.org3id_regexp = http://slexy.org
4page = /index.php/submit
45
5[format]6[format]
6user = author7user = author
7content = raw_paste8content = raw_paste
8title = desc9title = desc
9page = page
10language = language10language = language
11permissions = permissions11permissions = permissions
12linenumbers = linenumbers12linenumbers = linenumbers
@@ -16,7 +16,6 @@
1616
17[defaults]17[defaults]
18submit = Submit Paste18submit = Submit Paste
19page = /index.php/submit
20language = text19language = text
21permissions = 020permissions = 0
22comment =21comment =
2322
=== modified file 'pastebin.d/sprunge.us.conf'
--- pastebin.d/sprunge.us.conf 2012-06-13 16:41:21 +0000
+++ pastebin.d/sprunge.us.conf 2014-12-02 02:23:09 +0000
@@ -1,11 +1,9 @@
1[pastebin]1[pastebin]
2basename = sprunge.us2basename = sprunge.us
3regexp = http://sprunge.us3id_regexp = http://sprunge.us
4result_regexp=http://sprunge.us/(.*)$
5result_type = id
46
5[format]7[format]
6content = sprunge8content = sprunge
7format = lang9format = lang
8regexp = regexp
9
10[defaults]
11regexp=http://sprunge.us/(.*)$
1210
=== modified file 'pastebinit'
--- pastebinit 2014-01-18 04:51:35 +0000
+++ pastebinit 2014-12-02 02:23:09 +0000
@@ -4,7 +4,7 @@
4# Author: Stéphane Graber <stgraber@ubuntu.com>4# Author: Stéphane Graber <stgraber@ubuntu.com>
5# Written by Stéphane Graber <stgraber@stgraber.org>5# Written by Stéphane Graber <stgraber@stgraber.org>
6# Daniel Bartlett <dan@f-box.org>6# Daniel Bartlett <dan@f-box.org>
7# Last modification : Mon Jan 6 18:46:46 EST 20147# Last modification : Mon Nov 24 15:07:45 EST 2014
88
9# This program is free software; you can redistribute it and/or modify9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by10# it under the terms of the GNU General Public License as published by
@@ -23,224 +23,48 @@
23from __future__ import print_function23from __future__ import print_function
2424
25import sys25import sys
26import os
27import re
28import getopt
29import gettext
30import socket
31import xml.dom.minidom
32
26if sys.version[0] == "2":33if sys.version[0] == "2":
27 from ConfigParser import SafeConfigParser34 from ConfigParser import SafeConfigParser, NoOptionError, NoSectionError
28 from urllib import urlencode35 from urllib import urlencode
29 from urllib import FancyURLopener36 from urllib import FancyURLopener
30else:37else:
31 from configparser import SafeConfigParser38 #SafeConfigParser is now a deprecated alias to ConfigParser
39 from configparser import \
40 ConfigParser as SafeConfigParser, NoOptionError, NoSectionError
32 from urllib.parse import urlencode41 from urllib.parse import urlencode
33 from urllib.request import FancyURLopener42 from urllib.request import FancyURLopener
3443
35# Set the default pastebin
36defaultPB = "http://pastebin.com"
3744
38# Now try to override it with a distributor pastebin
39try:45try:
40 import lsb_release46 import json
41 release = lsb_release.get_distro_information()['ID'].lower()
42 if release == 'debian':
43 defaultPB = "http://paste.debian.net"
44 elif release == 'fedora':
45 defaultPB = "http://fpaste.org"
46 elif release == 'ubuntu':
47 defaultPB = "http://paste.ubuntu.com"
48except ImportError:47except ImportError:
49 pass48 json = None
5049
51try:50#Enables input redirection during tests
52 import getopt51stdin = sys.stdin
53 import gettext52stderr = sys.stderr
54 import os53stdout = sys.stdout
55 import re54
56 import socket55_ = gettext.gettext
57 import xml.dom.minidom56gettext.textdomain("pastebinit")
5857
59 try:58# Timeout after 5s
60 import json59socket.setdefaulttimeout(5)
61 except ImportError:60
62 json = None61# Version number to show in the usage
6362version = "1.4.1"
64 _ = gettext.gettext63config_path = os.path.expanduser("~/.pastebinit.xml")
65 gettext.textdomain("pastebinit")64verbose = False
6665
67 # Timeout after 5s66#Example configuration file string
68 socket.setdefaulttimeout(5)67config_example = """\
69
70 # Version number to show in the usage
71 version = "1.4.1"
72 configfile = os.path.expanduser("~/.pastebinit.xml")
73
74 # Custom urlopener to handle 401's
75 class pasteURLopener(FancyURLopener):
76 version = "Pastebinit v%s" % version
77
78 def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
79 return None
80
81 def preloadPastebins():
82 # Check several places for config files:
83 # - global config in /etc/pastebin.d
84 # - for source checkout, config in the checkout
85 # - user's overrides in ~/.pastebin.d
86 # Files found later override files found earlier.
87 pastebind = {}
88 for confdir in ['/usr/share/pastebin.d', '/etc/pastebin.d',
89 '/usr/local/etc/pastebin.d',
90 os.path.expanduser('~/.pastebin.d'),
91 os.path.join(
92 os.path.dirname(
93 os.path.realpath(__file__)), 'pastebin.d')]:
94 try:
95 confdirlist = os.listdir(confdir)
96 except OSError:
97 continue
98
99 for fileitem in confdirlist:
100 if fileitem.startswith('.') or not fileitem.endswith('.conf'):
101 continue
102
103 filename = os.path.join(confdir, fileitem)
104 instance = SafeConfigParser()
105 try:
106 instance.read(filename)
107 except UnicodeError:
108 continue
109
110 if not instance.has_section('pastebin'):
111 print(_('%s: no section [pastebin]') % filename,
112 file=sys.stderr)
113 continue
114
115 if not instance.has_option('pastebin', 'basename'):
116 print(_("%s: no 'basename' in [pastebin]") % filename,
117 file=sys.stderr)
118 continue
119
120 pastebind[instance.get('pastebin', 'basename')] = instance
121 return pastebind
122
123 # pastey.net obfuscates parent ids for replies. Rather than taking the
124 # post ID given as the parent ID, we must handle this by going to that
125 # post page and looking up what the invisible parent ID field will be
126 # set to for children.
127 def doParentFixup(website, paramname, parentid):
128 if parentid == "":
129 return ""
130 url_opener = pasteURLopener()
131 page = url_opener.open(website + '/' + parentid, None)
132 matches = re.split('<input.*?name="' + paramname + '".*?value="(.*?)"',
133 page.read())
134 if len(matches) <= 1 or re.match(parentid, matches[1]) is None:
135 # The obfuscated version didn't begin with the partial version,
136 # or unable to find the obfuscated version for some reason!
137 # Create a paste with no parent (should we throw, instead?)
138 return ""
139 return matches[1]
140
141 #Return the parameters depending of the pastebin used
142 def getParameters(website, pastebind, content, user, jabberid, version,
143 format, parentpid, permatag, title, username,
144 password):
145 "Return the parameters array for the selected pastebin"
146 params = {}
147 for paste_name, paste_config in pastebind.items():
148 basename = paste_config.get('pastebin', 'basename')
149 if basename == website or paste_name == website:
150 website = "http://%s" % basename
151
152 if re.search(paste_config.get('pastebin', 'regexp'), website):
153 if paste_config.has_option('pastebin', 'sizelimit'):
154 params['sizelimit'] = paste_config.get('pastebin',
155 'sizelimit')
156
157 for param in paste_config.options('format'):
158 paramname = paste_config.get('format', param)
159 if param == 'user':
160 params[paramname] = user
161 elif param == 'content':
162 params[paramname] = content
163 elif param == 'title':
164 params[paramname] = title
165 elif param == 'version':
166 params[paramname] = version
167 elif param == 'format':
168 params[paramname] = format
169 elif param == 'parentpid':
170 params[paramname] = doParentFixup(website, paramname,
171 parentpid)
172 elif param == 'permatag':
173 params[paramname] = permatag
174 elif param == 'username':
175 params[paramname] = username
176 elif param == 'password':
177 params[paramname] = password
178 elif param == 'jabberid':
179 params[paramname] = jabberid
180 else:
181 params[paramname] = paste_config.get('defaults', param)
182 if params:
183 return website, params
184 else:
185 print(_("Unknown website, please post a bugreport to request "
186 "this pastebin to be added (%s)") % website,
187 file=sys.stderr)
188 sys.exit(1)
189
190 #XML Handling methods
191 def getText(nodelist):
192 rc = ""
193 for node in nodelist:
194 if node.nodeType == node.TEXT_NODE:
195 rc = rc + node.data
196 return rc
197
198 def getNodes(nodes, title):
199 return nodes.getElementsByTagName(title)
200
201 def getFirstNode(nodes, title):
202 return getNodes(nodes, title)[0]
203
204 def getFirstNodeText(nodes, title):
205 return getText(getFirstNode(nodes, title).childNodes)
206
207 # Display usage instructions
208 def Usage(fd=sys.stdout):
209 print("pastebinit v" + version, file=fd)
210 print(_("Reads on stdin for input or takes a list of filenames "
211 "as parameters"), file=fd)
212 print(_("Optional arguments (not supported by all pastebins):"),
213 file=fd)
214 print(_("\t-a <author:default is '%s'>") % user, file=fd)
215 print(_("\t-b <pastebin url:default is '%s'>") % website, file=fd)
216 print(_("\t-f <format of paste:default is '%s'>") % format, file=fd)
217 print(_("\t-h This help screen"), file=fd)
218 print(_("\t-i <input file>"), file=fd)
219 print(_("\t-l List all supported pastebins"), file=fd)
220 print(_("\t-j <jabberid for notifications:default is '%s'>") %
221 jabberid, file=fd)
222 print(_("\t-m <permatag for all versions of a post:default is blank>"),
223 file=fd)
224 print(_("\t-r <parent posts ID:defaults to none>"), file=fd)
225 print(_("\t-t <title of paste:default is blank>"), file=fd)
226 print(_("\t-u <username> -p <password>"), file=fd)
227 print(_("\t-v Print the version number"), file=fd)
228
229 # Set defaults
230 website = defaultPB
231 user = os.environ.get('USER')
232 jabberid = ""
233 title = ""
234 permatag = ""
235 format = "text"
236 username = ""
237 password = ""
238 filenames = []
239 content = ""
240 parentpid = ""
241
242 #Example configuration file string
243 configexample = """\
244<pastebinit>68<pastebinit>
245<pastebin>http://paste.debian.net</pastebin>69<pastebin>http://paste.debian.net</pastebin>
246<author>A pastebinit user</author>70<author>A pastebinit user</author>
@@ -249,201 +73,396 @@
249</pastebinit>73</pastebinit>
250"""74"""
25175
252 #Open configuration file if it exists76
253 try:77class PasteURLopener(FancyURLopener):
254 f = open(configfile)78 """Custom urlopener to handle 401's"""
255 configtext = f.read()79 version = "Pastebinit v%s" % version
80
81 def __init__(self, fmt=''):
82 self.fmt = fmt
83 FancyURLopener.__init__(self)
84
85 def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
86 return None
87
88 def format_params(self, params):
89 if self.fmt == 'json':
90 if not json:
91 print(_("Could not find any json library."), file=stderr)
92 sys.exit(1)
93 return json.dumps(params)
94 else:
95 return urlencode(params)
96
97 def make_request(self, url, params):
98 post_params = self.format_params(params)
99
100 if self.fmt == 'json':
101 self.addheader('Content-type', 'text/json')
102
103 if verbose:
104 print("POSTing to: %s" % url, file=stderr)
105 print("\nParams: %s" % str(post_params), file=stderr)
106
107 try:
108 return self.open(url, post_params)
109 except KeyboardInterrupt:
110 print(_("KeyboardInterrupt caught."), file=stderr)
111 sys.exit(1)
112 except Exception as e:
113 print(_("Failed to contact the server: %s") % e, file=stderr)
114 sys.exit(1)
115
116
117def get_default_pastebin():
118 default = "http://pastebin.com"
119 try:
120 import lsb_release
121 return {
122 'debian': "http://paste.debian.net",
123 'fedora': "http://fpaste.org",
124 'ubuntu': "http://paste.ubuntu.com",
125 }[lsb_release.get_distro_information()['ID'].lower()]
126 except KeyError:
127 return default
128 except ImportError:
129 return default
130
131
132def defaults():
133 return {
134 'website': get_default_pastebin(),
135 'user': os.environ.get('USER'),
136 'format': "text",
137 'jabberid': "",
138 'title': "",
139 'permatag': "",
140 'username': "",
141 'password': "",
142 'parentpid': "",
143 'verbose': False,
144 }
145
146
147def usage(fd):
148 print("pastebinit v" + version, file=fd)
149 print(_("Reads on stdin for input or takes a list of filenames "
150 "as parameters"), file=fd)
151 print(_("Optional arguments (not supported by all pastebins):"), file=fd)
152 print(_("\t-a <author:default is '%s'>") % defaults()['user'], file=fd)
153 print(_("\t-b <pastebin url:default is '%s'>") % defaults()['website'],
154 file=fd)
155 print(_("\t-f <format of paste:default is '%s' "
156 "(or from pastebin config)>") % defaults()['format'], file=fd)
157 print(_("\t-h This help screen"), file=fd)
158 print(_("\t-i <input file>"), file=fd)
159 print(_("\t-l List all supported pastebins"), file=fd)
160 print(_("\t-j <jabberid for notifications:default is '%s'>") %
161 defaults()['jabberid'], file=fd)
162 print(_("\t-m <permatag for all versions of a post:default is blank>"),
163 file=fd)
164 print(_("\t-r <parent posts ID:defaults to none>"), file=fd)
165 print(_("\t-t <title of paste:default is blank>"), file=fd)
166 print(_("\t-u <username> -p <password>"), file=fd)
167 print(_("\t-v Print the version number"), file=fd)
168 print(_("\t--verbose Verbose output to stderr"), file=fd)
169
170
171def preloadPastebins():
172 """
173 Check several places for config files:
174 - global config in /etc/pastebin.d
175 - for source checkout, config in the checkout
176 - user's overrides in ~/.pastebin.d
177 Files found later override files found earlier.
178 """
179 pastebind = {}
180 for confdir in ['/usr/share/pastebin.d',
181 '/etc/pastebin.d',
182 '/usr/local/etc/pastebin.d',
183 os.path.expanduser('~/.pastebin.d'),
184 os.path.join(
185 os.path.dirname(os.path.realpath(__file__)),
186 'pastebin.d'),
187 ]:
188 try:
189 confdirlist = [
190 x for x in os.listdir(confdir)
191 if x.endswith('.conf') and not x.startswith('.')
192 ]
193 except OSError:
194 continue
195
196 for fileitem in confdirlist:
197 filename = os.path.join(confdir, fileitem)
198 parser = SafeConfigParser()
199 try:
200 parser.read(filename)
201 except UnicodeError:
202 print(_('%s: Unicode Error') % filename, file=stderr)
203 continue
204
205 if not parser.has_section('pastebin'):
206 print(_('%s: no section [pastebin]') % filename,
207 file=stderr)
208 continue
209
210 if not parser.has_option('pastebin', 'basename'):
211 print(_("%s: no 'basename' in [pastebin]") % filename,
212 file=stderr)
213 continue
214
215 pastebind[parser.get('pastebin', 'basename')] = parser
216 return pastebind
217
218
219def doParentFixup(paramname, settings):
220 """
221 pastey.net obfuscates parent ids for replies. Rather than taking the
222 post ID given as the parent ID, we must handle this by going to that
223 post page and looking up what the invisible parent ID field will be
224 set to for children.
225 """
226 website = settings['website']
227 parentid = settings['parentid']
228 if not parentid:
229 return ""
230 if not website.endswith("/"):
231 website += "/"
232 matches = re.split(
233 '<input.*?name="' + paramname + '".*?value="(.*?)"',
234 PasteURLopener(settings.get('post_format', '')).open(
235 website + parentid.lstrip('/'), None).read()
236 )
237 if len(matches) <= 1 or re.match(parentid, matches[1]) is None:
238 # The obfuscated version didn't begin with the partial version,
239 # or unable to find the obfuscated version for some reason!
240 # Create a paste with no parent (should we throw, instead?)
241 return ""
242 return matches[1]
243
244
245def getPasteConfig(website):
246 for paste_name, paste_config in preloadPastebins().items():
247 basename = paste_config.get('pastebin', 'basename')
248 if basename == website or paste_name == website:
249 website = "http://%s" % basename
250 if re.search(paste_config.get('pastebin', 'id_regexp'), website):
251 if not website.endswith("/"):
252 website += "/"
253 return paste_config, website
254
255 print(_("Unknown website, please post a bugreport to request this "
256 "pastebin to be added (%s)") % website,
257 file=stderr)
258 sys.exit(1)
259
260
261def readPasteConfig(paste_config, settings):
262 """Return the parameters array for the selected pastebin"""
263
264 for param in paste_config.options('pastebin'):
265 settings[param] = paste_config.get('pastebin', param)
266
267 post_params = {}
268 for param in paste_config.options('format'):
269 paramname = paste_config.get('format', param)
270
271 if param == 'content':
272 pass
273 elif param == 'parentpid':
274 post_params[paramname] = doParentFixup(paramname, settings)
275 else:
276 try:
277 post_params[paramname] = paste_config.get('defaults', param)
278 except NoOptionError:
279 pass
280 except NoSectionError:
281 pass
282
283 try:
284 post_params[paramname] = settings[param]
285 except KeyError:
286 pass
287
288 return post_params
289
290
291def getText(parent_node):
292 """Read the text from an XML node"""
293 rc = ""
294 for node in parent_node.childNodes:
295 if node.nodeType == node.TEXT_NODE:
296 rc += node.data
297 else:
298 rc += getText(node)
299 return rc
300
301
302def readFile(location, mode="r"):
303 f = open(location, mode)
304 try:
305 return f.read()
306 except KeyboardInterrupt:
307 print(_("KeyboardInterrupt caught."), file=stderr)
308 sys.exit(1)
309 except:
310 print(_("Unable to read from: %s") % location, file=stderr)
311 sys.exit(1)
312 finally:
256 f.close()313 f.close()
257 gotconfigxml = True314
315
316def readConfigFile(config_text):
317 """Update settings from config XML"""
318 try:
319 settings = {}
320 configxml = xml.dom.minidom.parseString(config_text)
321 for xml_var, setting in (('pastebin', 'website'),
322 ('author', 'user'),
323 ('format', 'format'),
324 ('jabberid', 'jabberid')):
325 try:
326 settings[setting] = getText(
327 configxml.getElementsByTagName(xml_var)[0])
328 except IndexError:
329 pass
330 return settings
258 except KeyboardInterrupt:331 except KeyboardInterrupt:
259 print(_("KeyboardInterrupt caught."), file=sys.stderr)332 print(_("KeyboardInterrupt caught."), file=stderr)
260 sys.exit(1)333 sys.exit(1)
261 except:334 except:
262 gotconfigxml = False335 print(_("Error parsing configuration file!"), file=stderr)
263336 print(_("Please ensure that your configuration file looks "
264 #Parse configuration file337 "similar to the following:"), file=stderr)
265 if gotconfigxml:338 print(config_example, file=stderr)
339 sys.exit(1)
340
341
342def getOpts(args=sys.argv[1:]):
343 try:
344 optlist, arglist = getopt.getopt(
345 args, 'hvli:f:b:a:r:j:t:m:u:p:', ('verbose',))
346 except getopt.GetoptError as e:
347 print(_("Invalid arguments: %s!" % e) + "\n", file=stderr)
348 usage(stderr)
349 sys.exit(1)
350 opts = dict(optlist)
351 opts['-i'] = [opt[1] for opt in optlist if opt[0] == "-i"] + arglist
352 return opts
353
354
355def readOptions(opts):
356 settings = {}
357
358 # Die if support information is requested
359 if "-h" in opts:
360 usage(stdout)
361 sys.exit(0)
362 if "-v" in opts:
363 print("pastebinit v" + version, file=stdout)
364 sys.exit(0)
365 if "-l" in opts:
366 print(_("Supported pastebins:"), file=stdout)
367 for pastebin in sorted(preloadPastebins()):
368 print("- %s" % pastebin, file=stdout)
369 sys.exit(0)
370
371 # Configure the environment
372 def setFromOpt(opt, label):
266 try:373 try:
267 configxml = xml.dom.minidom.parseString(configtext)374 settings[label] = opts[opt]
268 for variable, key in (('pastebin', 'website'), ('author', 'user'),375 except KeyError:
269 ('format', 'format'),376 pass
270 ('jabberid', 'jabberid')):377
271 try:378 setFromOpt('-b', 'website')
272 value = getFirstNodeText(configxml, variable)379 setFromOpt('-a', 'user')
273 vars()[key] = value380 setFromOpt('-f', 'format')
274 except:381 setFromOpt('-j', 'jabberid')
275 pass382 setFromOpt('-t', 'title')
276 except KeyboardInterrupt:383 setFromOpt('-m', 'permatag')
277 print(_("KeyboardInterrupt caught."), file=sys.stderr)384 setFromOpt('-u', 'username')
278 sys.exit(1)385 setFromOpt('-p', 'password')
279 except:386 setFromOpt('-r', 'parentpid')
280 print(_("Error parsing configuration file!"), file=sys.stderr)387 settings['verbose'] = "--verbose" in opts
281 print(_("Please ensure that your configuration file looks "388
282 "similar to the following:"), file=sys.stderr)389 settings['contents'] = [readFile(fname, "rb") for fname in opts['-i']]
283 print(configexample, file=sys.stderr)390 if not settings['contents']:
284 sys.exit(1)391 settings['contents'].append(stdin.read())
285392 return settings
286 # Get options393
394
395def readPageURL(page, settings):
396 website = settings['website']
397 result_type = settings.get('result_type', None)
287 try:398 try:
288 optlist, arglist = getopt.getopt(sys.argv[1:],399 # Check if we have to apply a regexp
289 'hvli:f:b:a:r:j:t:m:u:p:')400 page_url = ""
290 except KeyboardInterrupt:401 if result_type:
291 print(_("KeyboardInterrupt caught."), file=sys.stderr)402 result = page.read().decode('utf-8')
292 sys.exit(1)403 result_regex = settings.get('result_regexp', None)
293 except getopt.GetoptError:404 if result_regex:
294 print(_("Invalid arguments!\n"), file=sys.stderr)405 result = re.split(result_regex, result)[1]
295 Usage(sys.stderr)406
296 sys.exit(1)407 if result_type == 'url':
297408 page_url = result.strip()
298 # Get the config409 elif result_type == 'id':
299 pastebind = preloadPastebins()410 page_url = settings.get('target_url', website) + result.strip()
300411 else:
301 # Iterate through options412 raise ValueError(_("Unsupported result_type: %s" % result_type))
302 for opt in optlist:
303 if opt[0] == "-h":
304 Usage()
305 sys.exit(0)
306 if opt[0] == "-i":
307 filenames.append(opt[1])
308 elif opt[0] == "-f":
309 format = opt[1]
310 elif opt[0] == "-b":
311 website = opt[1]
312 elif opt[0] == "-a":
313 user = opt[1]
314 elif opt[0] == "-r":
315 parentpid = opt[1]
316 elif opt[0] == "-j":
317 jabberid = opt[1]
318 elif opt[0] == "-l":
319 print(_("Supported pastebins:"))
320 for pastebin in sorted(pastebind):
321 print("- %s" % pastebin)
322 sys.exit(0)
323 elif opt[0] == "-t":
324 title = opt[1]
325 elif opt[0] == "-m":
326 permatag = opt[1]
327 elif opt[0] == "-u":
328 username = opt[1]
329 elif opt[0] == "-p":
330 password = opt[1]
331 elif opt[0] == "-v":
332 print("pastebinit v" + version)
333 sys.exit(0)
334
335 filenames += arglist
336
337 if not filenames:
338 filenames.append("-")
339
340 contents = []
341 for filename in filenames:
342 # If - is specified as a filename read from stdin
343 # otherwise load the specified files.
344 if filename == "-":
345 content = sys.stdin.read()
346 else:413 else:
347 try:414 page_url = page.url
348 with open(filename, "rb") as fd:415
349 content = fd.read()416 # You may have posted to https:, but were given an http: url
350 except KeyboardInterrupt:417 if website.startswith('https:'):
351 print(_("KeyboardInterrupt caught."), file=sys.stderr)418 page_url = page_url.replace('http:', 'https:')
352 sys.exit(1)419 return page_url
353 except:420
354 print(_("Unable to read from: %s") % filename, file=sys.stderr)421 except KeyboardInterrupt:
355 sys.exit(1)422 print(_("KeyboardInterrupt caught."), file=stderr)
356423 sys.exit(1)
424 except:
425 print(_("Unable to read or parse the result page, it could be a "
426 "server timeout or a change server side, "
427 "try with another pastebin."), file=stderr)
428 sys.exit(1)
429
430
431def validateContents(settings):
432 """Check for invalid contents"""
433 for content in settings['contents']:
357 if not content:434 if not content:
358 print(_("You are trying to send an empty document, exiting."),435 print(_("You are trying to send an empty document, exiting."),
359 file=sys.stderr)436 file=stderr)
360 sys.exit(1)437 sys.exit(1)
361438
362 contents.append(content)439 if len(content) > int(settings.get('sizelimit', sys.maxsize)):
363440 print(_("The content you are trying to send exceeds "
364 for content in contents:441 "the pastebin's size limit."), file=stderr)
365 # Get the parameter array442 sys.exit(1)
366 website, params = getParameters(website, pastebind, content, user,443
367 jabberid, version, format, parentpid,444
368 permatag, title, username, password)445def main():
369446 try:
370 if not website.endswith("/"):447 settings = defaults()
371 website += "/"448 settings.update(readConfigFile(readFile(config_path)))
372449 settings.update(readOptions(getOpts()))
373 if "sizelimit" in params:450 verbose = settings['verbose']
374 if len(content) > int(params['sizelimit']):451
375 print(_("The content you are trying to send exceeds "452 paste_config, settings['website'] = getPasteConfig(settings['website'])
376 "the pastebin's size limit."), file=sys.stderr)453 params = readPasteConfig(paste_config, settings)
377 sys.exit(1)454
378 else:455 validateContents(settings)
379 del params['sizelimit']456 opener = PasteURLopener(settings.get('post_format', ''))
380457
381 reLink = None458 url = settings['website'] + settings.get('page', '').lstrip("/")
382 tmp_page = ""459 for content in settings['contents']:
383 if "page" in params:460 params[paste_config.get('format', 'content')] = content
384 website += params['page']461 page = opener.make_request(url, params)
385 tmp_page = params['page']462 print(readPageURL(page, settings), file=stdout)
386 del params["page"]463 except KeyboardInterrupt:
387 if "regexp" in params:464 print(_("KeyboardInterrupt caught."), file=stderr)
388 reLink = params['regexp']465 sys.exit(1)
389 del params["regexp"]466
390 if "target_url" in params:467if __name__ == '__main__':
391 target_url = params["target_url"]468 main()
392 del params["target_url"]
393 else:
394 target_url = None
395 if 'post_format' in params:
396 post_format = params['post_format']
397 del params['post_format']
398 else:
399 post_format = 'standard'
400
401 url_opener = pasteURLopener()
402
403 if post_format == 'json':
404 if json:
405 params = json.dumps(params)
406 url_opener.addheader('Content-type', 'text/json')
407 else:
408 print(_("Could not find any json library."), file=sys.stderr)
409 sys.exit(1)
410 else:
411 # Convert to a format usable with the HTML POST
412 params = urlencode(params)
413
414 # Send the informations and be redirected to the final page
415 try:
416 page = url_opener.open(website, params)
417 except Exception as e:
418 print(_("Failed to contact the server: %s") % e, file=sys.stderr)
419 sys.exit(1)
420
421 try:
422 # Check if we have to apply a regexp
423 if reLink:
424 if target_url:
425 website = target_url
426 else:
427 website = website.replace(tmp_page, "")
428
429 if reLink == '(.*)':
430 print(page.read().decode('utf-8').strip())
431 else:
432 # Print the result of the regexp
433 print(website + re.split(reLink,
434 page.read().decode('utf-8'))[1])
435 else:
436 # Get the final page and show the url
437 print(page.url)
438 except KeyboardInterrupt:
439 print(_("KeyboardInterrupt caught."), file=sys.stderr)
440 sys.exit(1)
441 except:
442 print(_("Unable to read or parse the result page, it could be a "
443 "server timeout or a change server side, "
444 "try with another pastebin."), file=sys.stderr)
445 sys.exit(1)
446
447except KeyboardInterrupt:
448 print(_("KeyboardInterrupt caught."), file=sys.stderr)
449 sys.exit(1)
450\ No newline at end of file469\ No newline at end of file
451470
=== added symlink 'pastebinit.py'
=== target is u'pastebinit'
=== added file 'test.py'
--- test.py 1970-01-01 00:00:00 +0000
+++ test.py 2014-12-02 02:23:09 +0000
@@ -0,0 +1,135 @@
1import unittest
2import pastebinit
3try:
4 from StringIO import StringIO
5except ImportError:
6 from io import StringIO
7
8pastebinit.stdin = StringIO('')
9pastebinit.stdout = StringIO('')
10pastebinit.stderr = StringIO('')
11
12
13class ConfigXMLTests(unittest.TestCase):
14
15 def test_config_xml_parse(self):
16 xml = """\
17 <pastebinit>
18 <pastebin>http://paste.debian.net</pastebin>
19 <author>A pastebinit user</author>
20 <jabberid>nobody@nowhere.org</jabberid>
21 <format>text</format>
22 </pastebinit>
23 """
24 out = {
25 'website': u'http://paste.debian.net',
26 'user': u'A pastebinit user',
27 'jabberid': u'nobody@nowhere.org',
28 'format': u'text',
29 }
30 assert pastebinit.readConfigFile(xml) == out, 'readConfigFile failed'
31
32 def test_config_xml_parse_missing(self):
33 xml = """\
34 <pastebinit>
35 <author>A pastebinit user</author>
36 <jabberid>nobody@nowhere.org</jabberid>
37 <format>text</format>
38 </pastebinit>
39 """
40 out = {
41 'user': u'A pastebinit user',
42 'jabberid': u'nobody@nowhere.org',
43 'format': u'text',
44 }
45 assert pastebinit.readConfigFile(xml) == out, 'readConfigFile failed'
46
47 def test_config_xml_parse_additional(self):
48 xml = """\
49 <pastebinit>
50 <author>A pastebinit user</author>
51 <jabberid>nobody@nowhere.org</jabberid>
52 <format>text</format>
53 <test>nonsense</test>
54 </pastebinit>
55 """
56 out = {
57 'user': u'A pastebinit user',
58 'jabberid': u'nobody@nowhere.org',
59 'format': u'text',
60 }
61 assert pastebinit.readConfigFile(xml) == out, 'readConfigFile failed'
62
63 def test_config_xml_parse_invalid(self):
64 try:
65 pastebinit.readConfigFile("invalid")
66 assert False, "Invalid file was parsed without error."
67 except SystemExit:
68 pass
69
70
71class GetOptsTests(unittest.TestCase):
72
73 def _check_arg(self, argname, settingname):
74 settings = pastebinit.readOptions(pastebinit.getOpts([argname, 'test']))
75 assert settings[settingname] == 'test', "Failed to read " + argname
76
77 def test_help(self):
78 try:
79 pastebinit.readOptions(['-h'])
80 assert False, "Failed to quit after help option"
81 except SystemExit:
82 pass
83
84 def test_list(self):
85 try:
86 pastebinit.readOptions(['-l'])
87 assert False, "Failed to quit after list option"
88 except SystemExit:
89 pass
90
91 def test_version(self):
92 try:
93 pastebinit.readOptions(['-v'])
94 assert False, "Failed to quit after version option"
95 except SystemExit:
96 pass
97
98 def test_website(self):
99 self._check_arg('-b', 'website')
100
101 def test_user(self):
102 self._check_arg('-a', 'user')
103
104 def test_format(self):
105 self._check_arg('-f', 'format')
106
107 def test_jabberid(self):
108 self._check_arg('-j', 'jabberid')
109
110 def test_title(self):
111 self._check_arg('-t', 'title')
112
113 def test_permatag(self):
114 self._check_arg('-m', 'permatag')
115
116 def test_username(self):
117 self._check_arg('-u', 'username')
118
119 def test_password(self):
120 self._check_arg('-p', 'password')
121
122 def test_parentpid(self):
123 self._check_arg('-r', 'parentpid')
124
125 def test_filenames(self):
126 opts = pastebinit.getOpts(['-i', 'testa',
127 '-i', 'testb',
128 '-i', 'testc',
129 ])
130 assert opts['-i'] == [
131 'testa','testb','testc'], "Failed to read filenames"
132
133
134if __name__ == "__main__":
135 unittest.main()
0136
=== modified file 'test.sh'
--- test.sh 2014-01-06 23:23:28 +0000
+++ test.sh 2014-12-02 02:23:09 +0000
@@ -1,11 +1,16 @@
1#!/bin/sh1#!/bin/sh
2teststring="blah blah blah"2#paste.debian.net needs 3 lines
3teststring="""\
4test from pastebinit
5test from pastebinit
6test from pastebinit
7"""
38
4for interpreter in python python3; do9for interpreter in python python3; do
5 for pastebin in $($interpreter pastebinit -l | egrep "^-" | sed "s/^- //g")10 for pastebin in $(ls pastebin.d/*.conf | sed 's~^pastebin.d/\(.*\)\.conf$~\1~')
6 do11 do
7 echo "Trying http://$pastebin ($interpreter)"12 echo "Trying http://$pastebin ($interpreter)"
8 URL=$(echo "$teststring\n$teststring\n$teststring" | $interpreter pastebinit -b http://$pastebin)13 URL=$(echo teststring | $interpreter ./pastebinit.py -b http://$pastebin)
914
10 if [ "$pastebin" = "paste.ubuntu.org.cn" ]; then15 if [ "$pastebin" = "paste.ubuntu.org.cn" ]; then
11 out=$(wget -O - -q "$URL" | gzip -d | grep "$teststring")16 out=$(wget -O - -q "$URL" | gzip -d | grep "$teststring")
@@ -14,9 +19,13 @@
14 fi19 fi
1520
16 if [ -n "$out" ]; then21 if [ -n "$out" ]; then
17 echo "PASS: http://$pastebin ($URL) ($interpreter)"22 echo "PASS: http://$pastebin"
23 echo " ($URL)"
24 echo " ($interpreter)"
18 else25 else
19 echo "FAIL: http://$pastebin ($URL) ($interpreter)"26 echo "FAIL: http://$pastebin"
27 echo " ($URL)"
28 echo " ($interpreter)"
20 fi29 fi
21 echo ""30 echo ""
22 done31 done

Subscribers

People subscribed via source and target branches

to all changes: