Now we have working paste sending to 4 places?. PrivateBin client is functional, we can use any PrivateBin with it!
This commit is contained in:
parent
9977b834e2
commit
fa369d636f
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.txt
|
423
cpaste.py
Normal file
423
cpaste.py
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
#######################################################################
|
||||||
|
#
|
||||||
|
# A script to paste to https://cpaste.org/
|
||||||
|
#
|
||||||
|
# Copyright (c) 2013-2019 Andreas Schneider <asn@samba.org>
|
||||||
|
# Copyright (c) 2013 Alexander Bokovoy <ab@samba.org>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
#######################################################################
|
||||||
|
#
|
||||||
|
# Requires: python3-requests
|
||||||
|
# Requires: python3-cryptography
|
||||||
|
#
|
||||||
|
# Optionally requires: python-Pygments
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
import zlib
|
||||||
|
import requests
|
||||||
|
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from optparse import OptionParser
|
||||||
|
from mimetypes import guess_type
|
||||||
|
try:
|
||||||
|
from pygments.lexers import guess_lexer, guess_lexer_for_filename
|
||||||
|
from pygments.util import ClassNotFound
|
||||||
|
guess_lang = True
|
||||||
|
except ImportError:
|
||||||
|
guess_lang = False
|
||||||
|
|
||||||
|
|
||||||
|
def base58_encode(v: bytes):
|
||||||
|
# 58 char alphabet
|
||||||
|
alphabet = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||||
|
alphabet_len = len(alphabet)
|
||||||
|
|
||||||
|
nPad = len(v)
|
||||||
|
v = v.lstrip(b'\0')
|
||||||
|
nPad -= len(v)
|
||||||
|
|
||||||
|
x = 0
|
||||||
|
for (i, c) in enumerate(v[::-1]):
|
||||||
|
if isinstance(c, str):
|
||||||
|
c = ord(c)
|
||||||
|
x += c << (8 * i)
|
||||||
|
|
||||||
|
string = b''
|
||||||
|
while x:
|
||||||
|
x, idx = divmod(x, alphabet_len)
|
||||||
|
string = alphabet[idx:idx+1] + string
|
||||||
|
|
||||||
|
return (alphabet[0:1] * nPad + string)
|
||||||
|
|
||||||
|
|
||||||
|
def json_encode(d):
|
||||||
|
return json.dumps(d, separators=(',', ':')).encode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# The encryption format is described here:
|
||||||
|
# https://github.com/PrivateBin/PrivateBin/wiki/Encryption-format
|
||||||
|
#
|
||||||
|
def privatebin_encrypt(paste_passphrase,
|
||||||
|
paste_password,
|
||||||
|
paste_plaintext,
|
||||||
|
paste_formatter,
|
||||||
|
paste_attachment_name,
|
||||||
|
paste_attachment,
|
||||||
|
paste_compress,
|
||||||
|
paste_burn,
|
||||||
|
paste_opendicussion):
|
||||||
|
if paste_password:
|
||||||
|
paste_passphrase += bytes(paste_password, 'utf-8')
|
||||||
|
|
||||||
|
# PBKDF
|
||||||
|
kdf_salt = bytes(os.urandom(8))
|
||||||
|
kdf_iterations = 100000
|
||||||
|
kdf_keysize = 256 # size of resulting kdf_key
|
||||||
|
|
||||||
|
backend = default_backend()
|
||||||
|
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
|
||||||
|
length=int(kdf_keysize / 8), # 256bit
|
||||||
|
salt=kdf_salt,
|
||||||
|
iterations=kdf_iterations,
|
||||||
|
backend=backend)
|
||||||
|
kdf_key = kdf.derive(paste_passphrase)
|
||||||
|
|
||||||
|
# AES-GCM
|
||||||
|
adata_size = 128
|
||||||
|
|
||||||
|
cipher_iv = bytes(os.urandom(int(adata_size / 8)))
|
||||||
|
cipher_algo = "aes"
|
||||||
|
cipher_mode = "gcm"
|
||||||
|
|
||||||
|
compression_type = "none"
|
||||||
|
if paste_compress:
|
||||||
|
compression_type = "zlib"
|
||||||
|
|
||||||
|
# compress plaintext
|
||||||
|
paste_data = {'paste': paste_plaintext}
|
||||||
|
if paste_attachment_name and paste_attachment:
|
||||||
|
paste_data['attachment'] = paste_attachment
|
||||||
|
paste_data['attachment_name'] = paste_attachment_name
|
||||||
|
print(paste_attachment_name)
|
||||||
|
print(paste_attachment)
|
||||||
|
|
||||||
|
if paste_compress:
|
||||||
|
zobj = zlib.compressobj(wbits=-zlib.MAX_WBITS)
|
||||||
|
paste_blob = zobj.compress(json_encode(paste_data)) + zobj.flush()
|
||||||
|
else:
|
||||||
|
paste_blob = json_encode(paste_data)
|
||||||
|
|
||||||
|
# Associated data to authenticate
|
||||||
|
paste_adata = [
|
||||||
|
[
|
||||||
|
base64.b64encode(cipher_iv).decode("utf-8"),
|
||||||
|
base64.b64encode(kdf_salt).decode("utf-8"),
|
||||||
|
kdf_iterations,
|
||||||
|
kdf_keysize,
|
||||||
|
adata_size,
|
||||||
|
cipher_algo,
|
||||||
|
cipher_mode,
|
||||||
|
compression_type,
|
||||||
|
],
|
||||||
|
paste_formatter,
|
||||||
|
int(paste_opendicussion),
|
||||||
|
int(paste_burn),
|
||||||
|
]
|
||||||
|
|
||||||
|
paste_adata_json = json_encode(paste_adata)
|
||||||
|
|
||||||
|
aesgcm = AESGCM(kdf_key)
|
||||||
|
ciphertext = aesgcm.encrypt(cipher_iv, paste_blob, paste_adata_json)
|
||||||
|
|
||||||
|
# Validate
|
||||||
|
# aesgcm.decrypt(cipher_iv, ciphertext, paste_adata_json)
|
||||||
|
|
||||||
|
paste_ciphertext = base64.b64encode(ciphertext).decode("utf-8")
|
||||||
|
|
||||||
|
return paste_adata, paste_ciphertext
|
||||||
|
|
||||||
|
|
||||||
|
def privatebin_send(paste_url,
|
||||||
|
paste_password,
|
||||||
|
paste_plaintext,
|
||||||
|
paste_formatter,
|
||||||
|
paste_attachment_name,
|
||||||
|
paste_attachment,
|
||||||
|
paste_compress,
|
||||||
|
paste_burn,
|
||||||
|
paste_opendicussion,
|
||||||
|
paste_expire):
|
||||||
|
paste_passphrase = bytes(os.urandom(32))
|
||||||
|
|
||||||
|
paste_adata, paste_ciphertext = privatebin_encrypt(paste_passphrase,
|
||||||
|
paste_password,
|
||||||
|
paste_plaintext,
|
||||||
|
paste_formatter,
|
||||||
|
paste_attachment_name,
|
||||||
|
paste_attachment,
|
||||||
|
paste_compress,
|
||||||
|
paste_burn,
|
||||||
|
paste_opendicussion)
|
||||||
|
|
||||||
|
# json payload for the post API
|
||||||
|
# https://github.com/PrivateBin/PrivateBin/wiki/API
|
||||||
|
payload = {
|
||||||
|
"v": 2,
|
||||||
|
"adata": paste_adata,
|
||||||
|
"ct": paste_ciphertext,
|
||||||
|
"meta": {
|
||||||
|
"expire": paste_expire,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# http content type
|
||||||
|
headers = {'X-Requested-With': 'JSONHttpRequest'}
|
||||||
|
|
||||||
|
r = requests.post(paste_url,
|
||||||
|
data=json_encode(payload),
|
||||||
|
headers=headers)
|
||||||
|
r.raise_for_status()
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = r.json()
|
||||||
|
except:
|
||||||
|
print('Oops, error: %s' % (r.text))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
paste_status = result['status']
|
||||||
|
if paste_status:
|
||||||
|
paste_message = result['message']
|
||||||
|
print("Oops, error: %s" % paste_message)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
paste_id = result['id']
|
||||||
|
paste_url_id = result['url']
|
||||||
|
paste_deletetoken = result['deletetoken']
|
||||||
|
|
||||||
|
print('Delete paste: %s/?pasteid=%s&deletetoken=%s' %
|
||||||
|
(paste_url, paste_id, paste_deletetoken))
|
||||||
|
# print('')
|
||||||
|
# print('### Paste (%s): %s%s#%s' %
|
||||||
|
# (paste_formatter,
|
||||||
|
# paste_url,
|
||||||
|
# paste_url_id,
|
||||||
|
# base58_encode(paste_passphrase).decode('utf-8')))
|
||||||
|
|
||||||
|
return paste_url, paste_url_id, base58_encode(paste_passphrase).decode('utf-8'), paste_deletetoken
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def guess_lang_formatter(paste_plaintext, paste_filename=None):
|
||||||
|
paste_formatter = 'plaintext'
|
||||||
|
|
||||||
|
# Map numpy to python because the numpy lexer gives false positives
|
||||||
|
# when guessing.
|
||||||
|
lexer_lang_map = {'numpy': 'python'}
|
||||||
|
|
||||||
|
# If we have a filename, try guessing using the more reliable
|
||||||
|
# guess_lexer_for_filename function.
|
||||||
|
# If that fails, try the guess_lexer function on the code.
|
||||||
|
lang = None
|
||||||
|
if paste_filename:
|
||||||
|
try:
|
||||||
|
lang = guess_lexer_for_filename(paste_filename,
|
||||||
|
paste_plaintext).name.lower()
|
||||||
|
except ClassNotFound:
|
||||||
|
print("No guess by filename")
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
lang = guess_lexer(paste_plaintext).name.lower()
|
||||||
|
except ClassNotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if lang:
|
||||||
|
if lang == 'markdown':
|
||||||
|
paste_formatter = 'markdown'
|
||||||
|
if lang != 'text only':
|
||||||
|
paste_formatter = 'syntaxhighlighting'
|
||||||
|
|
||||||
|
return paste_formatter
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = OptionParser()
|
||||||
|
|
||||||
|
parser.add_option("-f", "--file", dest="filename",
|
||||||
|
help="Read from a file instead of stdin",
|
||||||
|
metavar="FILE")
|
||||||
|
parser.add_option("-p", "--password", dest="password",
|
||||||
|
help="Create a password protected paste",
|
||||||
|
metavar="PASSWORD")
|
||||||
|
parser.add_option("-e", "--expire",
|
||||||
|
action="store", dest="expire", default="1day",
|
||||||
|
choices=["5min",
|
||||||
|
"10min",
|
||||||
|
"1hour",
|
||||||
|
"1day",
|
||||||
|
"1week",
|
||||||
|
"1month",
|
||||||
|
"1year",
|
||||||
|
"never"],
|
||||||
|
help="Expiration time of the paste (default: 1day)")
|
||||||
|
parser.add_option("-s", "--sourcecode",
|
||||||
|
action="store_true", dest="source", default=False,
|
||||||
|
help="Use source code highlighting")
|
||||||
|
parser.add_option("-m", "--markdown",
|
||||||
|
action="store_true", dest="markdown", default=False,
|
||||||
|
help="Parse paste as markdown")
|
||||||
|
parser.add_option("-b", "--burn",
|
||||||
|
action="store_true", dest="burn", default=False,
|
||||||
|
help="Burn paste after reading")
|
||||||
|
parser.add_option("-o", "--opendiscussion",
|
||||||
|
action="store_true", dest="opendiscussion",
|
||||||
|
default=False,
|
||||||
|
help="Allow discussion for the paste")
|
||||||
|
parser.add_option("-a", "--attachment", dest="attachment",
|
||||||
|
help="Specify path to a file to attachment to the paste",
|
||||||
|
metavar="FILE")
|
||||||
|
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
paste_url = 'https://cpaste.org'
|
||||||
|
paste_formatter = 'plaintext'
|
||||||
|
paste_compress = True
|
||||||
|
paste_expire = '1day'
|
||||||
|
paste_opendiscussion = 0
|
||||||
|
paste_burn = 0
|
||||||
|
paste_password = None
|
||||||
|
paste_attachment_name = None
|
||||||
|
paste_attachment = None
|
||||||
|
|
||||||
|
if options.filename:
|
||||||
|
f = open(options.filename)
|
||||||
|
if not f:
|
||||||
|
print("Oops, could not open file!")
|
||||||
|
|
||||||
|
paste_plaintext = f.read()
|
||||||
|
f.close()
|
||||||
|
else:
|
||||||
|
paste_plaintext = sys.stdin.read()
|
||||||
|
|
||||||
|
if not paste_plaintext:
|
||||||
|
print("Oops, we have no data")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if options.burn:
|
||||||
|
paste_burn = 1
|
||||||
|
|
||||||
|
if options.opendiscussion:
|
||||||
|
paste_opendiscussion = 1
|
||||||
|
|
||||||
|
if options.source:
|
||||||
|
paste_formatter = 'syntaxhighlighting'
|
||||||
|
elif options.markdown:
|
||||||
|
paste_formatter = 'markdown'
|
||||||
|
elif guess_lang:
|
||||||
|
paste_formatter = guess_lang_formatter(paste_plaintext,
|
||||||
|
options.filename)
|
||||||
|
|
||||||
|
if options.expire:
|
||||||
|
paste_expire = options.expire
|
||||||
|
|
||||||
|
if options.password:
|
||||||
|
paste_password = options.password
|
||||||
|
|
||||||
|
if options.attachment:
|
||||||
|
paste_attachment_name = os.path.basename(options.attachment)
|
||||||
|
mime = guess_type(options.attachment, strict=False)[0]
|
||||||
|
if not mime:
|
||||||
|
mime = 'application/octet-stream'
|
||||||
|
|
||||||
|
f = open(options.attachment, mode='rb')
|
||||||
|
if not f:
|
||||||
|
print("Oops, could not open file for attachment!")
|
||||||
|
|
||||||
|
data = f.read()
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
paste_attachment = 'data:%s;base64,' % (mime)
|
||||||
|
paste_attachment += base64.b64encode(data).decode('utf-8')
|
||||||
|
|
||||||
|
print(paste_url)
|
||||||
|
print(paste_password )
|
||||||
|
print(paste_plaintext )
|
||||||
|
print(paste_formatter )
|
||||||
|
print(paste_attachment_name )
|
||||||
|
print(paste_attachment )
|
||||||
|
print(paste_compress )
|
||||||
|
print(paste_burn )
|
||||||
|
print(paste_opendiscussion )
|
||||||
|
print(paste_expire )
|
||||||
|
|
||||||
|
privatebin_send(paste_url,
|
||||||
|
paste_password,
|
||||||
|
paste_plaintext,
|
||||||
|
paste_formatter,
|
||||||
|
paste_attachment_name,
|
||||||
|
paste_attachment,
|
||||||
|
paste_compress,
|
||||||
|
paste_burn,
|
||||||
|
paste_opendiscussion,
|
||||||
|
paste_expire)
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def publish_to_cpaste(file):
|
||||||
|
#paste_url = 'https://cpaste.org'
|
||||||
|
paste_url = 'https://paste.devsite.pl'
|
||||||
|
paste_formatter = 'plaintext'
|
||||||
|
paste_compress = True
|
||||||
|
paste_expire = '1day'
|
||||||
|
paste_opendiscussion = 0
|
||||||
|
paste_burn = 0
|
||||||
|
paste_password = None
|
||||||
|
paste_attachment_name = None
|
||||||
|
paste_attachment = None
|
||||||
|
|
||||||
|
f = open(file)
|
||||||
|
if not f:
|
||||||
|
print("Oops, could not open file!")
|
||||||
|
|
||||||
|
paste_plaintext = f.read()
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
paste_url, paste_id, paste_decrypt, paste_deletetoken = privatebin_send(paste_url,
|
||||||
|
paste_password,
|
||||||
|
paste_plaintext,
|
||||||
|
paste_formatter,
|
||||||
|
paste_attachment_name,
|
||||||
|
paste_attachment,
|
||||||
|
paste_compress,
|
||||||
|
paste_burn,
|
||||||
|
paste_opendiscussion,
|
||||||
|
paste_expire)
|
||||||
|
|
||||||
|
output = '%s%s#%s DELETE TOKEN: %s' % (paste_url, paste_id, paste_decrypt, paste_deletetoken)
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
84
mpaste.py
84
mpaste.py
@ -1,5 +1,11 @@
|
|||||||
import requests
|
import requests
|
||||||
|
import secrets
|
||||||
|
import base64
|
||||||
|
import tempfile
|
||||||
import socket
|
import socket
|
||||||
|
import os
|
||||||
|
|
||||||
|
from cpaste import publish_to_cpaste
|
||||||
|
|
||||||
def publish_to_termbin(content):
|
def publish_to_termbin(content):
|
||||||
host = 'termbin.com'
|
host = 'termbin.com'
|
||||||
@ -25,18 +31,8 @@ def publish_to_mozilla(content):
|
|||||||
}
|
}
|
||||||
response = requests.post(url, data=data)
|
response = requests.post(url, data=data)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
return f"https://pastebin.mozilla.org/{response.text}"
|
# Mozilla returns full link to the paste
|
||||||
return None
|
return f"{response.text}"
|
||||||
|
|
||||||
def publish_to_paste2(content):
|
|
||||||
url = 'https://paste2.org/api/create'
|
|
||||||
data = {
|
|
||||||
'content': content,
|
|
||||||
'lang': 'text'
|
|
||||||
}
|
|
||||||
response = requests.post(url, data=data)
|
|
||||||
if response.status_code == 200:
|
|
||||||
return f"https://paste2.org/{response.text}"
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def publish_to_dpaste(content):
|
def publish_to_dpaste(content):
|
||||||
@ -50,21 +46,46 @@ def publish_to_dpaste(content):
|
|||||||
return response.text.strip()
|
return response.text.strip()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def publish_to_pasteee(content, api_key):
|
|
||||||
url = 'https://paste.ee/api/v1/pastes'
|
def publish_to_pastesh(content):
|
||||||
|
HOST = 'https://paste.sh'
|
||||||
|
VERSION = 'v2'
|
||||||
|
|
||||||
|
# Generate ID
|
||||||
|
id = f"p{secrets.token_urlsafe(6)}"
|
||||||
|
|
||||||
|
# Create a temporary file
|
||||||
|
with tempfile.NamedTemporaryFile(mode='w+', delete=False) as temp_file:
|
||||||
|
temp_file_path = temp_file.name
|
||||||
|
|
||||||
|
# Write content to the temporary file
|
||||||
|
temp_file.write(content)
|
||||||
|
temp_file.flush()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Prepare headers
|
||||||
headers = {
|
headers = {
|
||||||
'X-Auth-Token': api_key
|
'X-Server-Key': '',
|
||||||
|
'Content-type': f'text/vnd.paste.sh-{VERSION}'
|
||||||
}
|
}
|
||||||
data = {
|
|
||||||
'description': 'File content',
|
# Send the request
|
||||||
'sections': [{'contents': content}]
|
with open(temp_file_path, 'rb') as file:
|
||||||
}
|
response = requests.post(f"{HOST}/{id}", headers=headers, data=file)
|
||||||
response = requests.post(url, json=data, headers=headers)
|
|
||||||
if response.status_code == 201:
|
if response.status_code == 200:
|
||||||
return response.json()['link']
|
return f"{HOST}/{id}"
|
||||||
|
else:
|
||||||
|
print(f"Error: Status code {response.status_code}")
|
||||||
|
print(f"Response: {response.text}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def publish_to_multiple_pastebins(file_path, pasteee_api_key=None):
|
finally:
|
||||||
|
# Clean up the temporary file
|
||||||
|
os.unlink(temp_file_path)
|
||||||
|
|
||||||
|
|
||||||
|
def publish_to_multiple_pastebins(file_path):
|
||||||
# Read the file content
|
# Read the file content
|
||||||
with open(file_path, 'r') as file:
|
with open(file_path, 'r') as file:
|
||||||
file_content = file.read()
|
file_content = file.read()
|
||||||
@ -81,29 +102,22 @@ def publish_to_multiple_pastebins(file_path, pasteee_api_key=None):
|
|||||||
if mozilla_url:
|
if mozilla_url:
|
||||||
results['Mozilla Pastebin'] = mozilla_url
|
results['Mozilla Pastebin'] = mozilla_url
|
||||||
|
|
||||||
# Publish to Paste2
|
|
||||||
paste2_url = publish_to_paste2(file_content)
|
|
||||||
if paste2_url:
|
|
||||||
results['Paste2'] = paste2_url
|
|
||||||
|
|
||||||
# Publish to Dpaste
|
# Publish to Dpaste
|
||||||
dpaste_url = publish_to_dpaste(file_content)
|
dpaste_url = publish_to_dpaste(file_content)
|
||||||
if dpaste_url:
|
if dpaste_url:
|
||||||
results['Dpaste'] = dpaste_url
|
results['Dpaste'] = dpaste_url
|
||||||
|
|
||||||
# Publish to Paste.ee (if API key is provided)
|
# Publish to CPaste
|
||||||
if pasteee_api_key:
|
cpaste_url = publish_to_cpaste(file_path)
|
||||||
pasteee_url = publish_to_pasteee(file_content, pasteee_api_key)
|
if cpaste_url:
|
||||||
if pasteee_url:
|
results['CPaste'] = cpaste_url
|
||||||
results['Paste.ee'] = pasteee_url
|
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
# Example usage
|
# Example usage
|
||||||
file_path = 'test.txt'
|
file_path = 'test.txt'
|
||||||
|
|
||||||
#pasteee_api_key = 'YOUR_PASTE_EE_API_KEY' # Optional, remove if not using
|
|
||||||
|
|
||||||
results = publish_to_multiple_pastebins(file_path)
|
results = publish_to_multiple_pastebins(file_path)
|
||||||
|
|
||||||
for service, url in results.items():
|
for service, url in results.items():
|
||||||
|
Loading…
Reference in New Issue
Block a user