Compare commits
2 Commits
32d3e2dfe1
...
582844bacf
Author | SHA1 | Date | |
---|---|---|---|
|
582844bacf | ||
|
5ffd0f0c03 |
26
TryUTF8Read.py
Executable file
26
TryUTF8Read.py
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
import sys
|
||||||
|
import codecs
|
||||||
|
|
||||||
|
def test_utf8_encoding(filepath):
|
||||||
|
try:
|
||||||
|
with codecs.open(filepath, 'r', 'utf-8') as testfile:
|
||||||
|
testfile.read()
|
||||||
|
#print(f"{filepath} is openable with UTF-8 encoding.")
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
print(f"{filepath} is not openable with UTF-8 encoding.")
|
||||||
|
print(f"Converting {filepath} from ISO-8859-1 to UTF-8...")
|
||||||
|
with codecs.open(filepath, 'r', 'iso-8859-1') as f:
|
||||||
|
content = f.read()
|
||||||
|
utf8_content = content.decode('iso-8859-1').encode('utf-8')
|
||||||
|
with codecs.open(filepath, 'w', 'utf-8') as f:
|
||||||
|
f.write(utf8_content)
|
||||||
|
print(f"{filepath} has been converted to UTF-8.")
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Please provide a file name as a command line argument.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
filepath = sys.argv[1]
|
||||||
|
test_utf8_encoding(filepath)
|
||||||
|
|
Binary file not shown.
20
btc_tracker/01042023/TheClient/bin/TheClient.py
Normal file
20
btc_tracker/01042023/TheClient/bin/TheClient.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
import os
|
||||||
|
import configparser
|
||||||
|
import requests
|
||||||
|
from datetime import datetime
|
||||||
|
from TheClient.database.db_utils import Database
|
||||||
|
from TheClient.graphing.graph_utils import Graph
|
||||||
|
|
||||||
|
def load_config(config_file):
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(config_file)
|
||||||
|
return config
|
||||||
|
|
||||||
|
def get_btc_price():
|
||||||
|
response = requests.get('https://api.binance.com/api/v3/avgPrice', params={'symbol': 'BTCUSDT'})
|
||||||
|
json_data = response.json()
|
||||||
|
return float(json_data['price'])
|
||||||
|
|
||||||
|
def main():
|
||||||
|
config = load_config(os.path.join(os.path.dirname(__file__), '..', 'config', 'The
|
0
btc_tracker/01042023/TheClient/database/__init__.py
Normal file
0
btc_tracker/01042023/TheClient/database/__init__.py
Normal file
27
btc_tracker/01042023/TheClient/database/db_utils.py
Normal file
27
btc_tracker/01042023/TheClient/database/db_utils.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import sqlite3
|
||||||
|
|
||||||
|
class Database():
|
||||||
|
def __init__(self, db_file):
|
||||||
|
self.db_file = db_file
|
||||||
|
self._create_table()
|
||||||
|
|
||||||
|
def _create_table(self):
|
||||||
|
with sqlite3.connect(self.db_file) as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('''CREATE TABLE IF NOT EXISTS timeseries
|
||||||
|
(timestamp INTEGER PRIMARY KEY, value REAL)''')
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
def insert_data(self, timestamp, value):
|
||||||
|
with sqlite3.connect(self.db_file) as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('''INSERT INTO timeseries (timestamp, value)
|
||||||
|
VALUES (?, ?)''', (timestamp, value))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
def fetch_data(self, limit):
|
||||||
|
with sqlite3.connect(self.db_file) as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('''SELECT timestamp, value FROM timeseries
|
||||||
|
ORDER BY timestamp DESC LIMIT ?''', (limit,))
|
||||||
|
return cursor.fetchall()
|
0
btc_tracker/01042023/TheClient/fetch/__init__.py
Normal file
0
btc_tracker/01042023/TheClient/fetch/__init__.py
Normal file
0
btc_tracker/01042023/TheClient/graphing/__init__.py
Normal file
0
btc_tracker/01042023/TheClient/graphing/__init__.py
Normal file
12
btc_tracker/01042023/TheClient/graphing/graph_utils.py
Normal file
12
btc_tracker/01042023/TheClient/graphing/graph_utils.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
class Graph():
|
||||||
|
def __init__(self, xdata, ydata):
|
||||||
|
self.fig, self.ax = plt.subplots()
|
||||||
|
self.line, = self.ax.plot(xdata, ydata)
|
||||||
|
|
||||||
|
def update_graph(self, xdata, ydata):
|
||||||
|
self.line.set_data(xdata, ydata)
|
||||||
|
self.ax.relim()
|
||||||
|
self.ax.autoscale_view()
|
||||||
|
self.fig.canvas.draw()
|
2
btc_tracker/01042023/TheClient/requirements.txt
Normal file
2
btc_tracker/01042023/TheClient/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
requests==2.25.1
|
||||||
|
matplotlib==3.6.2
|
0
btc_tracker/01042023/TheClient/tests/__init__.py
Normal file
0
btc_tracker/01042023/TheClient/tests/__init__.py
Normal file
100
chat.html
Normal file
100
chat.html
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
.chat-history {
|
||||||
|
height: 400px;
|
||||||
|
width: 33%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
float: middle;
|
||||||
|
}
|
||||||
|
.chat-input {
|
||||||
|
width: 33%;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
float: middle;
|
||||||
|
}
|
||||||
|
.user-info {
|
||||||
|
float: left;
|
||||||
|
width: 33%;
|
||||||
|
text-align: left;
|
||||||
|
margin: 10px;
|
||||||
|
height: 410px;
|
||||||
|
}
|
||||||
|
.user-info button {
|
||||||
|
display: block;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.chat-members {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
margin: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 10px;
|
||||||
|
height: 400px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.clearfix::after {
|
||||||
|
content: "";
|
||||||
|
clear: both;
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="chat-history" id="chatHistory"></div>
|
||||||
|
<div class="chat-input">
|
||||||
|
<textarea class="chat-input" id="chatInput"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="user-info">
|
||||||
|
<p id="userId">User ID: <span id="userIdValue">null</span></p>
|
||||||
|
<button id="generateIdButton">Generate ID</button>
|
||||||
|
<button id="saveNicknameButton">Save Nickname</button>
|
||||||
|
<div class="chat-members" id="chatMembers"></div>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
<script>
|
||||||
|
// generate a unique user id
|
||||||
|
document.getElementById("generateIdButton").addEventListener("click", function() {
|
||||||
|
const userIdValue = Date.now();
|
||||||
|
document.getElementById("userIdValue").innerHTML = userIdValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
// save interlocutor id to nickname
|
||||||
|
document.getElementById("saveNicknameButton").addEventListener("click", function() {
|
||||||
|
// your code here
|
||||||
|
});
|
||||||
|
|
||||||
|
// update chat history
|
||||||
|
function updateChatHistory(message) {
|
||||||
|
const chatHistory = document.getElementById("chatHistory");
|
||||||
|
chatHistory.innerHTML += `<p>${message}</p>`;
|
||||||
|
chatHistory.scrollTop = chatHistory.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update chat members list
|
||||||
|
function updateChatMembers(members) {
|
||||||
|
const chatMembers = document.getElementById("chatMembers");
|
||||||
|
chatMembers.innerHTML = "";
|
||||||
|
members.forEach(member => {
|
||||||
|
chatMembers.innerHTML += `<p>${member}</p>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle enter key press in chat input
|
||||||
|
document.getElementById("chatInput").addEventListener("keydown", function(event) {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
const message = document.getElementById("chatInput").value;
|
||||||
|
updateChatHistory(message);
|
||||||
|
document.getElementById("chatInput").value = "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
17
conver-iso-to-utf8.py
Executable file
17
conver-iso-to-utf8.py
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
import sys
|
||||||
|
import io
|
||||||
|
|
||||||
|
def convert_iso8859_to_utf8(filepath):
|
||||||
|
# open the file with ISO-8859-1 encoding
|
||||||
|
with io.open(filepath, 'r', encoding='iso-8859-1') as f:
|
||||||
|
# read the file's content
|
||||||
|
content = f.read()
|
||||||
|
# write the UTF-8 encoded content to a new file
|
||||||
|
with io.open(filepath, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(content)
|
||||||
|
print(f"{filepath} has been converted to UTF-8.")
|
||||||
|
|
||||||
|
|
||||||
|
filepath = sys.argv[1]
|
||||||
|
convert_iso8859_to_utf8(filepath)
|
36
letters/fifo-sample.py
Executable file
36
letters/fifo-sample.py
Executable file
@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import queue
|
||||||
|
import threading
|
||||||
|
|
||||||
|
def listen_to_fifo(q):
|
||||||
|
fifo = "/tmp/my_fifo"
|
||||||
|
if not os.path.exists(fifo):
|
||||||
|
os.mkfifo(fifo)
|
||||||
|
with open(fifo, 'r') as f:
|
||||||
|
while True:
|
||||||
|
data = f.readline().strip()
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
q.put(data)
|
||||||
|
|
||||||
|
def read_queue(q):
|
||||||
|
while True:
|
||||||
|
data = q.get()
|
||||||
|
if data == "reboot":
|
||||||
|
# Restart the script
|
||||||
|
print('## RESTARTING SCRIPT')
|
||||||
|
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||||
|
else:
|
||||||
|
print(data)
|
||||||
|
sys.stdout.flush()
|
||||||
|
q.task_done()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
q = queue.Queue()
|
||||||
|
t1 = threading.Thread(target=listen_to_fifo, args=(q,))
|
||||||
|
t2 = threading.Thread(target=read_queue, args=(q,))
|
||||||
|
t1.start()
|
||||||
|
t2.start()
|
||||||
|
q.join()
|
35
letters/fifo-sample_with-commands.py
Executable file
35
letters/fifo-sample_with-commands.py
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import queue
|
||||||
|
import threading
|
||||||
|
|
||||||
|
command_queue = queue.Queue()
|
||||||
|
fifo_file = "/tmp/my_fifo"
|
||||||
|
|
||||||
|
def listen_to_fifo(queue):
|
||||||
|
if not os.path.exists(fifo_file):
|
||||||
|
os.mkfifo(fifo_file)
|
||||||
|
with open(fifo_file, 'r') as f:
|
||||||
|
while True:
|
||||||
|
data = f.readline().strip()
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
queue.put(data)
|
||||||
|
|
||||||
|
def read_queue(queue):
|
||||||
|
while True:
|
||||||
|
data = queue.get()
|
||||||
|
if data == "reboot":
|
||||||
|
fifo_file.close()
|
||||||
|
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||||
|
print(data)
|
||||||
|
sys.stdout.flush()
|
||||||
|
queue.task_done()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
t1 = threading.Thread(target=listen_to_fifo, args=(command_queue,))
|
||||||
|
t2 = threading.Thread(target=read_queue, args=(command_queue,))
|
||||||
|
t1.start()
|
||||||
|
t2.start()
|
||||||
|
command_queue.join()
|
27
letters/sample_function.py
Normal file
27
letters/sample_function.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import ecdsa
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
def get_btc_ohlc_data(server_url, user_private_key):
|
||||||
|
# Load user's ECDSA private key
|
||||||
|
user_private_key = ecdsa.SigningKey.from_string(binascii.unhexlify(user_private_key), curve=ecdsa.SECP256k1)
|
||||||
|
# Get server public key from endpoint
|
||||||
|
server_public_key_hex = requests.get(server_url + "/serverkey").text
|
||||||
|
server_public_key = ecdsa.VerifyingKey.from_string(binascii.unhexlify(server_public_key_hex), curve=ecdsa.SECP256k1)
|
||||||
|
# Get timestamp
|
||||||
|
timestamp = str(int(time.time()))
|
||||||
|
# Create signature using user's private key
|
||||||
|
signature = binascii.hexlify(user_private_key.sign(bytes(timestamp, 'utf-8'))).decode("utf-8")
|
||||||
|
# Create authentication header
|
||||||
|
auth_header = {"auth": timestamp + ":" + signature}
|
||||||
|
# Make request to server with auth header
|
||||||
|
response = requests.get(server_url + "/t", headers=auth_header)
|
||||||
|
# Verify server's signature
|
||||||
|
server_signature = response.headers["signature"]
|
||||||
|
if server_public_key.verify(bytes(server_signature, 'utf-8'), bytes(timestamp, 'utf-8')):
|
||||||
|
# If signature is valid, return json data
|
||||||
|
return json.loads(response.text)
|
||||||
|
else:
|
||||||
|
# If signature is invalid, return error message
|
||||||
|
return {"error": "Invalid signature from server"}
|
377
pastedb/cpaste.py
Executable file
377
pastedb/cpaste.py
Executable file
@ -0,0 +1,377 @@
|
|||||||
|
#!/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')))
|
||||||
|
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
49
pastedb/example_post.py
Executable file
49
pastedb/example_post.py
Executable file
@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Define your JSON object
|
||||||
|
my_json = {'name': 'John', 'age': 30, 'city': 'New York'}
|
||||||
|
|
||||||
|
# Define the API endpoints for the services you want to use
|
||||||
|
gist_url = 'https://api.github.com/gists'
|
||||||
|
hastebin_url = 'https://hastebin.com/documents'
|
||||||
|
pastie_url = 'https://pastie.io/documents'
|
||||||
|
ghostbin_url = 'https://ghostbin.com/paste/new'
|
||||||
|
codepad_url = 'https://codepad.co/snippet_api'
|
||||||
|
termbin_url = 'https://termbin.com/documents'
|
||||||
|
|
||||||
|
# Define a function to upload the JSON object to each service
|
||||||
|
def upload_to_service(url, data):
|
||||||
|
response = requests.post(url, json=data)
|
||||||
|
if response.status_code == 200:
|
||||||
|
return response.json().get('key') or response.json().get('id')
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Upload the JSON object to each service and print the URLs
|
||||||
|
gist_key = upload_to_service(gist_url, {'public': True, 'files': {'my_json.json': {'content': json.dumps(my_json)}}})
|
||||||
|
if gist_key:
|
||||||
|
print(f'Gist URL: https://gist.github.com/{gist_key}')
|
||||||
|
|
||||||
|
hastebin_key = upload_to_service(hastebin_url, json.dumps(my_json))
|
||||||
|
if hastebin_key:
|
||||||
|
print(f'Hastebin URL: https://hastebin.com/{hastebin_key}.json')
|
||||||
|
|
||||||
|
pastie_key = upload_to_service(pastie_url, json.dumps(my_json))
|
||||||
|
if pastie_key:
|
||||||
|
print(f'Pastie URL: https://pastie.io/{pastie_key}')
|
||||||
|
|
||||||
|
ghostbin_key = upload_to_service(ghostbin_url, {'text': json.dumps(my_json)})
|
||||||
|
if ghostbin_key:
|
||||||
|
print(f'Ghostbin URL: https://ghostbin.com/{ghostbin_key}')
|
||||||
|
|
||||||
|
codepad_key = upload_to_service(codepad_url, {'code': json.dumps(my_json)})
|
||||||
|
if codepad_key:
|
||||||
|
print(f'Codepad URL: https://codepad.co/{codepad_key}.json')
|
||||||
|
|
||||||
|
termbin_key = upload_to_service(termbin_url, json.dumps(my_json))
|
||||||
|
if termbin_key:
|
||||||
|
print(f'Termbin URL: https://termbin.com/{termbin_key}')
|
||||||
|
|
15
pastedb/example_post_controlc.py
Normal file
15
pastedb/example_post_controlc.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
|
url = "https://controlc.com/api.php?action=save"
|
||||||
|
|
||||||
|
# Text to be pasted
|
||||||
|
text = "Hello, world!"
|
||||||
|
|
||||||
|
# Create a new paste
|
||||||
|
response = requests.post(url, data={"c": text})
|
||||||
|
|
||||||
|
# Extract the URL of the newly created paste
|
||||||
|
paste_url = response.text
|
||||||
|
|
||||||
|
print(f"Paste URL: {paste_url}")
|
||||||
|
|
18
pastedb/example_post_hastebin.py
Normal file
18
pastedb/example_post_hastebin.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Define your JSON object
|
||||||
|
my_json = {'name': 'John', 'age': 30, 'city': 'New York'}
|
||||||
|
|
||||||
|
# Define the API endpoint for Hastebin
|
||||||
|
hastebin_url = 'https://hastebin.com/documents'
|
||||||
|
|
||||||
|
# Upload the JSON object to Hastebin and get the URL
|
||||||
|
response = requests.post(hastebin_url, data=json.dumps(my_json))
|
||||||
|
if response.status_code == 200:
|
||||||
|
key = response.json()['key']
|
||||||
|
hastebin_url = f'https://hastebin.com/{key}'
|
||||||
|
print(f'JSON object uploaded to Hastebin: {hastebin_url}')
|
||||||
|
else:
|
||||||
|
print('Error uploading JSON object to Hastebin')
|
||||||
|
|
52
pastedb/example_post_multi_backends.py
Normal file
52
pastedb/example_post_multi_backends.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import json
|
||||||
|
import requests
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
|
||||||
|
# generate random name for upload
|
||||||
|
def generate_name():
|
||||||
|
timestamp = str(int(time.time()))
|
||||||
|
rand = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz', k=3))
|
||||||
|
return timestamp + '-' + rand
|
||||||
|
|
||||||
|
# define json object to upload
|
||||||
|
data = {
|
||||||
|
"name": "Alice",
|
||||||
|
"age": 25,
|
||||||
|
"city": "New York"
|
||||||
|
}
|
||||||
|
|
||||||
|
# add timestamp and md5sum to the json object
|
||||||
|
data['timestamp'] = int(time.time())
|
||||||
|
json_str = json.dumps(data)
|
||||||
|
hash_md5 = hashlib.md5(json_str.encode())
|
||||||
|
data['md5sum'] = hash_md5.hexdigest()
|
||||||
|
|
||||||
|
# upload to pastie
|
||||||
|
pastie_url = 'https://www.pastie.io/documents'
|
||||||
|
pastie_resp = requests.post(pastie_url, data=json_str.encode(), headers={'Content-Type': 'application/json'})
|
||||||
|
pastie_key = pastie_resp.json()['key']
|
||||||
|
pastie_name = 'pastie-' + generate_name()
|
||||||
|
|
||||||
|
# store pastie info in dictionary
|
||||||
|
paste_dict = {}
|
||||||
|
paste_dict[pastie_name] = {'service': 'pastie', 'key': pastie_key, 'md5sum': data['md5sum']}
|
||||||
|
|
||||||
|
# upload to termbin
|
||||||
|
termbin_url = 'https://termbin.com'
|
||||||
|
termbin_resp = requests.post(termbin_url, data=json_str.encode(), headers={'Content-Type': 'text/plain'})
|
||||||
|
termbin_key = termbin_resp.text.strip()
|
||||||
|
termbin_name = 'termbin-' + generate_name()
|
||||||
|
|
||||||
|
# store termbin info in dictionary
|
||||||
|
paste_dict[termbin_name] = {'service': 'termbin', 'key': termbin_key, 'md5sum': data['md5sum']}
|
||||||
|
|
||||||
|
# write paste dictionary to file
|
||||||
|
with open('paste_dict.json', 'a') as f:
|
||||||
|
f.write(json.dumps(paste_dict, indent=4))
|
||||||
|
f.write('\n')
|
||||||
|
|
||||||
|
# print out paste dictionary
|
||||||
|
print(json.dumps(paste_dict, indent=4))
|
||||||
|
|
71
pastedb/example_post_multi_handling.py
Normal file
71
pastedb/example_post_multi_handling.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import requests
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
# Function to generate a unique name for the upload
|
||||||
|
def generate_upload_name():
|
||||||
|
timestamp = int(time.time())
|
||||||
|
rand_str = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz', k=3))
|
||||||
|
return f"{timestamp}-{rand_str}"
|
||||||
|
|
||||||
|
|
||||||
|
# Function to upload JSON data to termbin
|
||||||
|
def upload_to_termbin(data):
|
||||||
|
try:
|
||||||
|
resp = requests.post('https://termbin.com', data=data.encode('utf-8'), timeout=5)
|
||||||
|
if resp.status_code == 200:
|
||||||
|
key = resp.text.strip()
|
||||||
|
md5sum = hashlib.md5(data.encode('utf-8')).hexdigest()
|
||||||
|
return {'service': 'termbin', 'key': key, 'md5sum': md5sum}
|
||||||
|
else:
|
||||||
|
print(f"Failed to upload to termbin.com. Response code: {resp.status_code}")
|
||||||
|
return None
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"Failed to upload to termbin.com. Error: {str(e)}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# Function to upload JSON data to pastie
|
||||||
|
def upload_to_pastie(data):
|
||||||
|
try:
|
||||||
|
resp = requests.post('https://pastie.io/documents', data=data.encode('utf-8'), timeout=5)
|
||||||
|
if resp.status_code == 200:
|
||||||
|
key = resp.json()['key']
|
||||||
|
md5sum = hashlib.md5(data.encode('utf-8')).hexdigest()
|
||||||
|
return {'service': 'pastie', 'key': key, 'md5sum': md5sum}
|
||||||
|
else:
|
||||||
|
print(f"Failed to upload to pastie.io. Response code: {resp.status_code}")
|
||||||
|
return None
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"Failed to upload to pastie.io. Error: {str(e)}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# Upload data to both termbin and pastie
|
||||||
|
def upload_data_to_services(data):
|
||||||
|
upload_name = generate_upload_name()
|
||||||
|
print(f"\nUploading data to services with name {upload_name}...\n")
|
||||||
|
paste_dict = {'name': upload_name}
|
||||||
|
services = {'termbin': upload_to_termbin, 'pastie': upload_to_pastie}
|
||||||
|
for service, upload_function in services.items():
|
||||||
|
result = upload_function(data)
|
||||||
|
if result is not None:
|
||||||
|
paste_dict[service] = result
|
||||||
|
print(f"JSON object uploaded to {service}: https://{service}.com/{result['key']}")
|
||||||
|
with open('paste_dict.json', 'a+') as f:
|
||||||
|
f.write(json.dumps(paste_dict) + '\n')
|
||||||
|
print(f"\nUploads completed successfully.")
|
||||||
|
|
||||||
|
|
||||||
|
# Test function
|
||||||
|
def test():
|
||||||
|
data = '{"name": "John Doe", "age": 30, "city": "New York"}'
|
||||||
|
upload_data_to_services(data)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test()
|
||||||
|
|
19
pastedb/example_post_paste2org.py
Normal file
19
pastedb/example_post_paste2org.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
|
# Set the URL of the Paste2.org API endpoint
|
||||||
|
url = 'https://paste2.org/'
|
||||||
|
|
||||||
|
# Get the input from the user
|
||||||
|
text = 'Enter text to upload'
|
||||||
|
|
||||||
|
# Send the HTTP POST request to the Paste2.org API with the text as the request body
|
||||||
|
response = requests.post(url, data=text.encode('utf-8'))
|
||||||
|
|
||||||
|
# Get the URL of the uploaded text from the response JSON
|
||||||
|
if response.status_code == 200:
|
||||||
|
paste_id = response.json().get('id')
|
||||||
|
paste_url = f'https://paste2.org/{paste_id}'
|
||||||
|
print('Uploaded to:', paste_url)
|
||||||
|
else:
|
||||||
|
print('Error uploading text:', response.text)
|
||||||
|
|
46
pastedb/example_post_pastie.py
Normal file
46
pastedb/example_post_pastie.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
# Define your JSON object with a unique timestamp and MD5 hash
|
||||||
|
my_json = {'timestamp': int(time.time()), 'name': 'John', 'age': 30, 'city': 'New York'}
|
||||||
|
json_str = json.dumps(my_json, sort_keys=True)
|
||||||
|
md5_hash = hashlib.md5(json_str.encode()).hexdigest()
|
||||||
|
my_json['md5'] = md5_hash
|
||||||
|
|
||||||
|
# Define the API endpoint for Pastie
|
||||||
|
pastie_url = 'https://pastie.io/documents'
|
||||||
|
|
||||||
|
# Upload the JSON object to Pastie and get the URL
|
||||||
|
response = requests.post(pastie_url, data=json.dumps(my_json))
|
||||||
|
if response.status_code == 200:
|
||||||
|
key = response.json()['key']
|
||||||
|
pastie_url = f'https://pastie.io/{key}'
|
||||||
|
print(f'JSON object uploaded to Pastie: {pastie_url}')
|
||||||
|
|
||||||
|
# Add the URL and service name to the dictionary for later querying
|
||||||
|
paste_dict = {}
|
||||||
|
if os.path.isfile('paste_dict.json'):
|
||||||
|
with open('paste_dict.json', 'r') as f:
|
||||||
|
paste_dict = json.load(f)
|
||||||
|
paste_dict[key] = {'url': pastie_url, 'service': 'Pastie'}
|
||||||
|
|
||||||
|
# Write the URL dictionary to a file on disk
|
||||||
|
with open('paste_dict.json', 'w') as f:
|
||||||
|
json.dump(paste_dict, f, indent=4)
|
||||||
|
else:
|
||||||
|
print('Error uploading JSON object to Pastie')
|
||||||
|
|
||||||
|
# Query the dictionary for the URL of a specific paste
|
||||||
|
if os.path.isfile('paste_dict.json'):
|
||||||
|
with open('paste_dict.json', 'r') as f:
|
||||||
|
paste_dict = json.load(f)
|
||||||
|
key_to_query = key if key in paste_dict else list(paste_dict.keys())[0]
|
||||||
|
url = paste_dict[key_to_query]['url']
|
||||||
|
service = paste_dict[key_to_query]['service']
|
||||||
|
print(f'URL for paste with key {key_to_query} (stored on {service}): {url}')
|
||||||
|
else:
|
||||||
|
print('URL dictionary file not found')
|
||||||
|
|
18
pastedb/example_post_snippet.py
Normal file
18
pastedb/example_post_snippet.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
|
url = "https://snippet.host/api/documents"
|
||||||
|
|
||||||
|
# Text to be pasted
|
||||||
|
text = "Hello, world!"
|
||||||
|
|
||||||
|
# Create a new paste
|
||||||
|
response = requests.post(url, data=text)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Extract the URL of the newly created paste
|
||||||
|
paste_url = f"https://snippet.host/{response.json()['key']}"
|
||||||
|
print(f"Paste URL: {paste_url}")
|
||||||
|
else:
|
||||||
|
# If the response code is not 200, print the response body for debugging
|
||||||
|
print(f"Error: {response.text}")
|
||||||
|
|
39
pastedb/example_post_sprunge.py
Normal file
39
pastedb/example_post_sprunge.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
url = 'http://sprunge.us'
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
try:
|
||||||
|
json_data = json.dumps(data)
|
||||||
|
md5sum = hashlib.md5(json_data.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
# Send the HTTP POST request to the Sprunge API
|
||||||
|
response = requests.post(url, data={'sprunge': json_data})
|
||||||
|
if response.status_code == 200:
|
||||||
|
|
||||||
|
# Get the URL of the uploaded text from the response body
|
||||||
|
sprunge_url = response.text.strip()
|
||||||
|
|
||||||
|
print('Uploaded to:', sprunge_url)
|
||||||
|
|
||||||
|
# Use a regular expression to extract the random ID from the URL
|
||||||
|
match = re.match(r'^http://sprunge\.us/(\w+)$', sprunge_url)
|
||||||
|
if match:
|
||||||
|
random_id = match.group(1)
|
||||||
|
print('Random ID:', random_id)
|
||||||
|
key = "sprunge_" + random_id + '_' + md5sum[:5]
|
||||||
|
else:
|
||||||
|
print('Invalid Sprunge URL:', sprunge_url)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"service": "sprunge",
|
||||||
|
"name": key,
|
||||||
|
"key": sprunge_url,
|
||||||
|
"md5sum": md5sum
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
return None
|
5
pastedb/example_post_zerobin.py
Normal file
5
pastedb/example_post_zerobin.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
|
data = {"data": 'print("Hello!")'}
|
||||||
|
r = requests.post("https://zerobin.net/?paste", data=data)
|
||||||
|
print(f"URL: {r.text}")
|
331
pastedb/lodgeit.py
Executable file
331
pastedb/lodgeit.py
Executable file
@ -0,0 +1,331 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
LodgeIt!
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
A script that pastes stuff into the lodgeit pastebin.
|
||||||
|
|
||||||
|
.lodgeitrc / _lodgeitrc
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Under UNIX create a file called ``~/.lodgeitrc``, under Windows
|
||||||
|
create a file ``%APPDATA%/_lodgeitrc`` to override defaults::
|
||||||
|
|
||||||
|
language=default_language
|
||||||
|
clipboard=true/false
|
||||||
|
open_browser=true/false
|
||||||
|
encoding=fallback_charset
|
||||||
|
|
||||||
|
:authors: 2007-2010 Georg Brandl <georg@python.org>,
|
||||||
|
2006 Armin Ronacher <armin.ronacher@active-4.com>,
|
||||||
|
2006 Matt Good <matt@matt-good.net>,
|
||||||
|
2005 Raphael Slinckx <raphael@slinckx.net>
|
||||||
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from six import text_type
|
||||||
|
from optparse import OptionParser
|
||||||
|
|
||||||
|
|
||||||
|
SCRIPT_NAME = os.path.basename(sys.argv[0])
|
||||||
|
VERSION = '0.3'
|
||||||
|
SETTING_KEYS = ['author', 'title', 'language', 'private', 'clipboard',
|
||||||
|
'open_browser']
|
||||||
|
|
||||||
|
# global server proxy
|
||||||
|
_xmlrpc_service = None
|
||||||
|
_server_name = None
|
||||||
|
|
||||||
|
|
||||||
|
def fail(msg, code):
|
||||||
|
"""Bail out with an error message."""
|
||||||
|
print('ERROR: %s' % msg, file=sys.stderr)
|
||||||
|
sys.exit(code)
|
||||||
|
|
||||||
|
|
||||||
|
def load_default_settings():
|
||||||
|
"""Load the defaults from the lodgeitrc file."""
|
||||||
|
settings = {
|
||||||
|
'language': None,
|
||||||
|
'clipboard': True,
|
||||||
|
'open_browser': False,
|
||||||
|
'encoding': 'iso-8859-15',
|
||||||
|
'server_name': 'http://paste.openstack.org',
|
||||||
|
}
|
||||||
|
rcfile = None
|
||||||
|
if os.name == 'posix':
|
||||||
|
rcfile = os.path.expanduser('~/.lodgeitrc')
|
||||||
|
elif os.name == 'nt' and 'APPDATA' in os.environ:
|
||||||
|
rcfile = os.path.expandvars(r'$APPDATA\_lodgeitrc')
|
||||||
|
if rcfile:
|
||||||
|
try:
|
||||||
|
f = open(rcfile)
|
||||||
|
for line in f:
|
||||||
|
if line.strip()[:1] in '#;':
|
||||||
|
continue
|
||||||
|
p = line.split('=', 1)
|
||||||
|
if len(p) == 2:
|
||||||
|
key = p[0].strip().lower()
|
||||||
|
if key in settings:
|
||||||
|
if key in ('clipboard', 'open_browser'):
|
||||||
|
settings[key] = p[1].strip().lower() in \
|
||||||
|
('true', '1', 'on', 'yes')
|
||||||
|
else:
|
||||||
|
settings[key] = p[1].strip()
|
||||||
|
f.close()
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
settings['tags'] = []
|
||||||
|
settings['title'] = None
|
||||||
|
return settings
|
||||||
|
|
||||||
|
|
||||||
|
def make_utf8(text, encoding):
|
||||||
|
"""Convert a text to UTF-8, brute-force."""
|
||||||
|
try:
|
||||||
|
u = text_type(text, 'utf-8')
|
||||||
|
uenc = 'utf-8'
|
||||||
|
except UnicodeError:
|
||||||
|
try:
|
||||||
|
u = text_type(text, encoding)
|
||||||
|
uenc = 'utf-8'
|
||||||
|
except UnicodeError:
|
||||||
|
u = text_type(text, 'iso-8859-15', 'ignore')
|
||||||
|
uenc = 'iso-8859-15'
|
||||||
|
try:
|
||||||
|
import chardet
|
||||||
|
except ImportError:
|
||||||
|
return u.encode('utf-8')
|
||||||
|
d = chardet.detect(text)
|
||||||
|
if d['encoding'] == uenc:
|
||||||
|
return u.encode('utf-8')
|
||||||
|
return text_type(text, d['encoding'], 'ignore').encode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def get_xmlrpc_service():
|
||||||
|
"""Create the XMLRPC server proxy and cache it."""
|
||||||
|
global _xmlrpc_service
|
||||||
|
import xmlrpclib
|
||||||
|
if _xmlrpc_service is None:
|
||||||
|
try:
|
||||||
|
_xmlrpc_service = xmlrpclib.ServerProxy(_server_name + 'xmlrpc/',
|
||||||
|
allow_none=True)
|
||||||
|
except Exception as err:
|
||||||
|
fail('Could not connect to Pastebin: %s' % err, -1)
|
||||||
|
return _xmlrpc_service
|
||||||
|
|
||||||
|
|
||||||
|
def copy_url(url):
|
||||||
|
"""Copy the url into the clipboard."""
|
||||||
|
# try windows first
|
||||||
|
try:
|
||||||
|
import win32clipboard
|
||||||
|
except ImportError:
|
||||||
|
# then give pbcopy a try. do that before gtk because
|
||||||
|
# gtk might be installed on os x but nobody is interested
|
||||||
|
# in the X11 clipboard there.
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
for prog in 'pbcopy', 'xclip':
|
||||||
|
try:
|
||||||
|
client = Popen([prog], stdin=PIPE)
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
client.stdin.write(url)
|
||||||
|
client.stdin.close()
|
||||||
|
client.wait()
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
import pygtk
|
||||||
|
pygtk.require('2.0')
|
||||||
|
import gtk
|
||||||
|
import gobject
|
||||||
|
except ImportError:
|
||||||
|
return
|
||||||
|
gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD).set_text(url)
|
||||||
|
gobject.idle_add(gtk.main_quit)
|
||||||
|
gtk.main()
|
||||||
|
else:
|
||||||
|
win32clipboard.OpenClipboard()
|
||||||
|
win32clipboard.EmptyClipboard()
|
||||||
|
win32clipboard.SetClipboardText(url)
|
||||||
|
win32clipboard.CloseClipboard()
|
||||||
|
|
||||||
|
|
||||||
|
def open_webbrowser(url):
|
||||||
|
"""Open a new browser window."""
|
||||||
|
import webbrowser
|
||||||
|
webbrowser.open(url)
|
||||||
|
|
||||||
|
|
||||||
|
def language_exists(language):
|
||||||
|
"""Check if a language alias exists."""
|
||||||
|
xmlrpc = get_xmlrpc_service()
|
||||||
|
langs = xmlrpc.pastes.getLanguages()
|
||||||
|
return language in langs
|
||||||
|
|
||||||
|
|
||||||
|
def get_mimetype(data, filename):
|
||||||
|
"""Try to get MIME type from data."""
|
||||||
|
try:
|
||||||
|
import gnomevfs
|
||||||
|
except ImportError:
|
||||||
|
from mimetypes import guess_type
|
||||||
|
if filename:
|
||||||
|
return guess_type(filename)[0]
|
||||||
|
else:
|
||||||
|
if filename:
|
||||||
|
return gnomevfs.get_mime_type(os.path.abspath(filename))
|
||||||
|
return gnomevfs.get_mime_type_for_data(data)
|
||||||
|
|
||||||
|
|
||||||
|
def print_languages():
|
||||||
|
"""Print a list of all supported languages, with description."""
|
||||||
|
xmlrpc = get_xmlrpc_service()
|
||||||
|
languages = xmlrpc.pastes.getLanguages().items()
|
||||||
|
languages.sort(key=lambda a: a[1].lower())
|
||||||
|
print('Supported Languages:')
|
||||||
|
for alias, name in languages:
|
||||||
|
print(' %-30s%s' % (alias, name))
|
||||||
|
|
||||||
|
|
||||||
|
def download_paste(uid):
|
||||||
|
"""Download a paste given by ID."""
|
||||||
|
xmlrpc = get_xmlrpc_service()
|
||||||
|
paste = xmlrpc.pastes.getPaste(uid)
|
||||||
|
if not paste:
|
||||||
|
fail('Paste "%s" does not exist.' % uid, 5)
|
||||||
|
print(paste['code'].encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
|
def create_paste(code, language, filename, mimetype, private):
|
||||||
|
"""Create a new paste."""
|
||||||
|
xmlrpc = get_xmlrpc_service()
|
||||||
|
rv = xmlrpc.pastes.newPaste(language, code, None, filename, mimetype,
|
||||||
|
private)
|
||||||
|
if not rv:
|
||||||
|
fail('Could not create paste. Something went wrong '
|
||||||
|
'on the server side.', 4)
|
||||||
|
return rv
|
||||||
|
|
||||||
|
|
||||||
|
def compile_paste(filenames, langopt):
|
||||||
|
"""Create a single paste out of zero, one or multiple files."""
|
||||||
|
def read_file(f):
|
||||||
|
try:
|
||||||
|
return f.read()
|
||||||
|
finally:
|
||||||
|
f.close()
|
||||||
|
mime = ''
|
||||||
|
lang = langopt or ''
|
||||||
|
if not filenames:
|
||||||
|
data = read_file(sys.stdin)
|
||||||
|
print('Pasting...')
|
||||||
|
if not langopt:
|
||||||
|
mime = get_mimetype(data, '') or ''
|
||||||
|
fname = ''
|
||||||
|
elif len(filenames) == 1:
|
||||||
|
fname = filenames[0]
|
||||||
|
data = read_file(open(filenames[0], 'rb'))
|
||||||
|
if not langopt:
|
||||||
|
mime = get_mimetype(data, filenames[0]) or ''
|
||||||
|
else:
|
||||||
|
result = []
|
||||||
|
for fname in filenames:
|
||||||
|
data = read_file(open(fname, 'rb'))
|
||||||
|
if langopt:
|
||||||
|
result.append('### %s [%s]\n\n' % (fname, langopt))
|
||||||
|
else:
|
||||||
|
result.append('### %s\n\n' % fname)
|
||||||
|
result.append(data)
|
||||||
|
result.append('\n\n')
|
||||||
|
data = ''.join(result)
|
||||||
|
lang = 'multi'
|
||||||
|
fname = ''
|
||||||
|
return data, lang, fname, mime
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main script entry point."""
|
||||||
|
global _server_name
|
||||||
|
|
||||||
|
usage = ('Usage: %%prog [options] [FILE ...]\n\n'
|
||||||
|
'Read the files and paste their contents to LodgeIt pastebin.\n'
|
||||||
|
'If no file is given, read from standard input.\n'
|
||||||
|
'If multiple files are given, they are put into a single paste.')
|
||||||
|
parser = OptionParser(usage=usage)
|
||||||
|
|
||||||
|
settings = load_default_settings()
|
||||||
|
|
||||||
|
parser.add_option('-v', '--version', action='store_true',
|
||||||
|
help='Print script version')
|
||||||
|
parser.add_option('-L', '--languages', action='store_true', default=False,
|
||||||
|
help='Retrieve a list of supported languages')
|
||||||
|
parser.add_option('-l', '--language', default=settings['language'],
|
||||||
|
help='Used syntax highlighter for the file')
|
||||||
|
parser.add_option('-e', '--encoding', default=settings['encoding'],
|
||||||
|
help='Specify the encoding of a file (default is '
|
||||||
|
'utf-8 or guessing if available)')
|
||||||
|
parser.add_option('-b', '--open-browser', dest='open_browser',
|
||||||
|
action='store_true',
|
||||||
|
default=settings['open_browser'],
|
||||||
|
help='Open the paste in a web browser')
|
||||||
|
parser.add_option('-p', '--private', action='store_true', default=False,
|
||||||
|
help='Paste as private')
|
||||||
|
parser.add_option('--no-clipboard', dest='clipboard',
|
||||||
|
action='store_false',
|
||||||
|
default=settings['clipboard'],
|
||||||
|
help="Don't copy the url into the clipboard")
|
||||||
|
parser.add_option('--download', metavar='UID',
|
||||||
|
help='Download a given paste')
|
||||||
|
parser.add_option('-s', '--server', default=settings['server_name'],
|
||||||
|
dest='server_name',
|
||||||
|
help="Specify the pastebin to send data")
|
||||||
|
opts, args = parser.parse_args()
|
||||||
|
|
||||||
|
# The global available server name
|
||||||
|
_server_name = opts.server_name
|
||||||
|
if not _server_name.endswith('/'):
|
||||||
|
_server_name += '/'
|
||||||
|
|
||||||
|
# special modes of operation:
|
||||||
|
# - paste script version
|
||||||
|
if opts.version:
|
||||||
|
print('%s: version %s' % (SCRIPT_NAME, VERSION))
|
||||||
|
sys.exit()
|
||||||
|
# - print list of languages
|
||||||
|
elif opts.languages:
|
||||||
|
print_languages()
|
||||||
|
sys.exit()
|
||||||
|
# - download Paste
|
||||||
|
elif opts.download:
|
||||||
|
download_paste(opts.download)
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
# check language if given
|
||||||
|
if opts.language and not language_exists(opts.language):
|
||||||
|
fail('Language %s is not supported.' % opts.language, 3)
|
||||||
|
|
||||||
|
# load file(s)
|
||||||
|
try:
|
||||||
|
data, language, filename, mimetype = compile_paste(args, opts.language)
|
||||||
|
except Exception as err:
|
||||||
|
fail('Error while reading the file(s): %s' % err, 2)
|
||||||
|
if not data:
|
||||||
|
fail('Aborted, no content to paste.', 4)
|
||||||
|
|
||||||
|
# create paste
|
||||||
|
code = make_utf8(data, opts.encoding)
|
||||||
|
pid = create_paste(code, language, filename, mimetype, opts.private)
|
||||||
|
url = '%sshow/%s/' % (_server_name, pid)
|
||||||
|
print(url)
|
||||||
|
if opts.open_browser:
|
||||||
|
open_webbrowser(url)
|
||||||
|
if opts.clipboard:
|
||||||
|
copy_url(url)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
69
pastedb/lodgeit_python3.py
Executable file
69
pastedb/lodgeit_python3.py
Executable file
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
LodgeIt!
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
A script that pastes stuff into the lodgeit pastebin.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
VERSION = '0.3'
|
||||||
|
SERVER_NAME = 'http://paste.openstack.org/'
|
||||||
|
|
||||||
|
def upload_paste(paste_content, title=None, language=None, private=None):
|
||||||
|
"""
|
||||||
|
Uploads a paste to LodgeIt!
|
||||||
|
|
||||||
|
:param paste_content: the content of the paste to upload
|
||||||
|
:param title: the title of the paste (optional)
|
||||||
|
:param language: the language of the paste (optional)
|
||||||
|
:param private: whether the paste should be private (optional)
|
||||||
|
:return: the URL of the uploaded paste
|
||||||
|
"""
|
||||||
|
# build the POST data
|
||||||
|
data = {
|
||||||
|
'content': paste_content.encode('utf-8'),
|
||||||
|
'format': 'text',
|
||||||
|
}
|
||||||
|
if title is not None:
|
||||||
|
data['name'] = title
|
||||||
|
if language is not None:
|
||||||
|
data['language'] = language
|
||||||
|
if private is not None:
|
||||||
|
data['private'] = private
|
||||||
|
|
||||||
|
# make the request
|
||||||
|
url = urllib.parse.urljoin(SERVER_NAME, '/pastes')
|
||||||
|
request = urllib.request.Request(url, data=urllib.parse.urlencode(data).encode('utf-8'))
|
||||||
|
response = urllib.request.urlopen(request)
|
||||||
|
|
||||||
|
# parse the response and return the URL of the new paste
|
||||||
|
location = response.getheader('Location')
|
||||||
|
if location is None:
|
||||||
|
raise ValueError('Could not find the URL of the new paste')
|
||||||
|
return location
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# parse the command-line arguments
|
||||||
|
parser = argparse.ArgumentParser(description='Upload a paste to LodgeIt!')
|
||||||
|
parser.add_argument('filename', help='the name of the file to upload')
|
||||||
|
parser.add_argument('--title', help='the title of the paste')
|
||||||
|
parser.add_argument('--language', help='the language of the paste')
|
||||||
|
parser.add_argument('--private', action='store_true', help='make the paste private')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# read the content of the file to upload
|
||||||
|
with open(args.filename, 'r') as f:
|
||||||
|
paste_content = f.read()
|
||||||
|
|
||||||
|
# upload the paste and print the URL of the new paste
|
||||||
|
url = upload_paste(paste_content, args.title, args.language, args.private)
|
||||||
|
print(url)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
30
pastedb/old_upload.py
Normal file
30
pastedb/old_upload.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import hashlib
|
||||||
|
from services import pastie, dpaste, rentry, defau, sprunge, opendev
|
||||||
|
from data import data
|
||||||
|
|
||||||
|
def save(data):
|
||||||
|
# Upload to the available services
|
||||||
|
paste_dict = {'name': name}
|
||||||
|
successes = []
|
||||||
|
failures = []
|
||||||
|
for service in [defau]:
|
||||||
|
try:
|
||||||
|
result = service.upload(data)
|
||||||
|
add_data(result["service"], result["key"], result["md5sum"] )
|
||||||
|
successes.append(result['name'])
|
||||||
|
except Exception as e:
|
||||||
|
failures.append(f"{service.__name__}: {str(e)}")
|
||||||
|
|
||||||
|
# Print upload results
|
||||||
|
print(f"Upload successful to {len(successes)}/{len(successes)+len(failures)} services:")
|
||||||
|
for name in successes:
|
||||||
|
print(f"- {name}")
|
||||||
|
if failures:
|
||||||
|
print("Upload failed to the following services:")
|
||||||
|
for error in failures:
|
||||||
|
print(f"- {error}")
|
||||||
|
|
||||||
|
print(f"Your paste trace is: {name}")
|
26
pastedb/opendev.py
Executable file
26
pastedb/opendev.py
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
import requests
|
||||||
|
|
||||||
|
url = 'https://paste.opendev.org/json/'
|
||||||
|
|
||||||
|
# read input from stdin
|
||||||
|
input_str = sys.stdin.read()
|
||||||
|
|
||||||
|
# create data for new paste
|
||||||
|
data = {
|
||||||
|
'language': '',
|
||||||
|
'code': input_str,
|
||||||
|
'private': False
|
||||||
|
}
|
||||||
|
|
||||||
|
# send request to create new paste
|
||||||
|
response = requests.post(url + '?method=pastes.newPaste', data=data)
|
||||||
|
|
||||||
|
# extract URL of newly created paste from response
|
||||||
|
paste_id = response.text.strip()
|
||||||
|
paste_url = f'https://paste.opendev.org/show/{paste_id}'
|
||||||
|
|
||||||
|
# print URL of newly created paste
|
||||||
|
print(paste_url)
|
||||||
|
|
45
pastedb/opendev_2nd.py
Executable file
45
pastedb/opendev_2nd.py
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
url = 'https://paste.opendev.org/json/'
|
||||||
|
|
||||||
|
# read input from stdin
|
||||||
|
data = '{ "name": "joe", "age": 55}'
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
try:
|
||||||
|
content = json.dumps(data)
|
||||||
|
|
||||||
|
# create JSON payload for new paste
|
||||||
|
payload = {
|
||||||
|
'language': 'text',
|
||||||
|
'code': content,
|
||||||
|
'private': False
|
||||||
|
#'expire': '1day'
|
||||||
|
}
|
||||||
|
|
||||||
|
# send request to create new paste
|
||||||
|
response = requests.post(url + '?method=pastes.newPaste', json=payload)
|
||||||
|
|
||||||
|
status = response.status_code
|
||||||
|
paste_id = response.json()['data']
|
||||||
|
|
||||||
|
if status == 200:
|
||||||
|
#print(f'JSON object uploaded to dpaste.com: {dpaste_url}')
|
||||||
|
md5sum = hashlib.md5(content.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'service': 'url',
|
||||||
|
'key': paste_id,
|
||||||
|
'md5sum': md5sum,
|
||||||
|
'name': 'opendev_' + paste_id + '_' + md5sum[:5]
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
return None
|
||||||
|
# we can get the paste back by:
|
||||||
|
## $ > curl -d '{"paste_id":819463}' -H 'Content-Type: application/json' https://paste.opendev.org/json/?method=pastes.getPaste |jq .data.code
|
12
pastedb/paste_dict.json
Normal file
12
pastedb/paste_dict.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "1680462198-dxx",
|
||||||
|
"pastie": {
|
||||||
|
"service": "pastie",
|
||||||
|
"key": "jpllic",
|
||||||
|
"md5sum": "5e87ba1e0d151a399c0418343842b94d"
|
||||||
|
},
|
||||||
|
"ogqfsh": {
|
||||||
|
"url": "https://pastie.io/ogqfsh",
|
||||||
|
"service": "Pastie"
|
||||||
|
}
|
||||||
|
}
|
1
pastedb/pastedb01/data.json
Normal file
1
pastedb/pastedb01/data.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
ed566cf8f839c936bfd5582f1af6aa7d0d8457fcdd3c421d4424eedb41d5868155a6e04a291c4add0a2ec88a287d0371605d8ff9be6cbf2ba91d67097e39c0333cbf57515d9072d998d1dee110f3ecab
|
0
pastedb/pastedb01/data/__init__.py
Normal file
0
pastedb/pastedb01/data/__init__.py
Normal file
BIN
pastedb/pastedb01/data/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/data/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
pastedb/pastedb01/data/__pycache__/data.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/data/__pycache__/data.cpython-310.pyc
Normal file
Binary file not shown.
122
pastedb/pastedb01/data/data.py
Normal file
122
pastedb/pastedb01/data/data.py
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
"""
|
||||||
|
This module provides functions for managing and saving data in a dictionary object. It also supports encryption and decryption of the data when saving and loading it to/from disk. The functions in this module include:
|
||||||
|
|
||||||
|
set_encryption_key(key: bytes): sets the encryption key to be used for encrypting the data.
|
||||||
|
add_data(service_tag: str, key: str, md5sum: str) -> str: adds data for a service to the data dictionary.
|
||||||
|
save_data(filename: str, data: dict, key=None): writes the data dictionary to disk as a JSON object. If a key is provided, it encrypts the data using the AES symmetric encryption algorithm before writing to disk.
|
||||||
|
encrypt_data(data: bytes) -> bytes: encrypts data using the AES symmetric encryption algorithm.
|
||||||
|
load_data(file_path: str) -> Dict: loads the data from a file and returns it as a dictionary. If the file is encrypted, it uses the provided key to decrypt it before returning the data.
|
||||||
|
|
||||||
|
This module depends on the following packages: hashlib, Crypto, and collections.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
from collections import defaultdict
|
||||||
|
from Cryptodome.Cipher import AES
|
||||||
|
from Cryptodome.Util import Padding
|
||||||
|
from cryptography.fernet import Fernet
|
||||||
|
|
||||||
|
data = defaultdict(lambda: {"timestamp": 0, "services": {}})
|
||||||
|
|
||||||
|
_ENCRYPTION_KEY = None
|
||||||
|
|
||||||
|
def set_encryption_key(key: bytes):
|
||||||
|
global _ENCRYPTION_KEY
|
||||||
|
_ENCRYPTION_KEY = key
|
||||||
|
|
||||||
|
|
||||||
|
def add_data(service_tag: str, key: str, md5sum: str) -> str:
|
||||||
|
"""
|
||||||
|
Adds data for a service to the `data` dictionary.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
service_tag (str): A string representing the service being added.
|
||||||
|
key (str): A string representing the key for the service being added.
|
||||||
|
md5sum (str): A string representing the MD5 checksum for the service being added.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: A string representing the unique ID of the run that the data was added to.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Generate a unique ID for the run
|
||||||
|
run_id = f"run-{hashlib.sha256(str(data).encode()).hexdigest()[:6]}"
|
||||||
|
timestamp = int(time.time())
|
||||||
|
|
||||||
|
# Add the service data to the run
|
||||||
|
data[run_id]["timestamp"] = timestamp
|
||||||
|
data[run_id]["services"][service_tag] = {"key": key, "md5sum": md5sum}
|
||||||
|
|
||||||
|
return run_id
|
||||||
|
|
||||||
|
|
||||||
|
def save_data(filename: str, data: dict, key=None):
|
||||||
|
"""
|
||||||
|
Writes the data dictionary to disk as a JSON object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
filename (str): A string representing the filename to write the data to.
|
||||||
|
data (dict): A dictionary representing the data to be written to disk.
|
||||||
|
key (bytes): Optional bytes representing a key to use for encryption.
|
||||||
|
"""
|
||||||
|
with open(filename, "w") as f:
|
||||||
|
# Serialize the data dictionary as a JSON object
|
||||||
|
json_data = json.dumps(data)
|
||||||
|
|
||||||
|
# If a key is provided, encrypt the JSON data
|
||||||
|
if _ENCRYPTION_KEY:
|
||||||
|
# Encrypt the data using the key
|
||||||
|
encrypted_data = encrypt_data(json_data.encode())
|
||||||
|
|
||||||
|
# Write the encrypted data to the file
|
||||||
|
f.write(encrypted_data.hex())
|
||||||
|
else:
|
||||||
|
# Write the unencrypted JSON data to the file
|
||||||
|
print("you need to set the encryption key first.")
|
||||||
|
|
||||||
|
|
||||||
|
def encrypt_data(data: bytes) -> bytes:
|
||||||
|
"""
|
||||||
|
Encrypts data using the AES symmetric encryption algorithm.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data (bytes): A bytes object representing the data to be encrypted.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bytes: A bytes object representing the encrypted data.
|
||||||
|
"""
|
||||||
|
# Generate a random initialization vector (IV)
|
||||||
|
iv = os.urandom(AES.block_size)
|
||||||
|
|
||||||
|
# Pad the data to a multiple of the block size
|
||||||
|
padded_data = Padding.pad(data, AES.block_size)
|
||||||
|
|
||||||
|
# Create an AES cipher object
|
||||||
|
cipher = AES.new(_ENCRYPTION_KEY, AES.MODE_CBC, iv)
|
||||||
|
|
||||||
|
# Encrypt the data using CBC mode
|
||||||
|
encrypted_data = cipher.encrypt(padded_data)
|
||||||
|
|
||||||
|
# Prepend the IV to the encrypted data
|
||||||
|
return iv + encrypted_data
|
||||||
|
|
||||||
|
|
||||||
|
def load_data(file_path: str, key=None) -> dict:
|
||||||
|
"""
|
||||||
|
Load the data from a file and return it as a dictionary.
|
||||||
|
|
||||||
|
:param file_path: The path to the file to load.
|
||||||
|
:param key: The key to use to decrypt the file.
|
||||||
|
:return: A dictionary representing the data from the file.
|
||||||
|
"""
|
||||||
|
if _ENCRYPTION_KEY:
|
||||||
|
with open(file_path, "rb") as f:
|
||||||
|
ciphertext = f.read()
|
||||||
|
|
||||||
|
fernet = Fernet(_ENCRYPTION_KEY.encode())
|
||||||
|
plaintext = fernet.decrypt(ciphertext)
|
||||||
|
return json.loads(plaintext.decode())
|
||||||
|
else:
|
||||||
|
print("you need to set the encryption key first.")
|
||||||
|
return '{"you need to set the encryption key first."}'
|
BIN
pastedb/pastedb01/external/pastebinit_1.5.1-1_all.deb
vendored
Normal file
BIN
pastedb/pastedb01/external/pastebinit_1.5.1-1_all.deb
vendored
Normal file
Binary file not shown.
161
pastedb/pastedb01/external/rentry
vendored
Executable file
161
pastedb/pastedb01/external/rentry
vendored
Executable file
@ -0,0 +1,161 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import getopt
|
||||||
|
import http.cookiejar
|
||||||
|
import sys
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
from http.cookies import SimpleCookie
|
||||||
|
from json import loads as json_loads
|
||||||
|
from os import environ
|
||||||
|
|
||||||
|
_headers = {"Referer": 'https://rentry.co'}
|
||||||
|
|
||||||
|
|
||||||
|
class UrllibClient:
|
||||||
|
"""Simple HTTP Session Client, keeps cookies."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.cookie_jar = http.cookiejar.CookieJar()
|
||||||
|
self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.cookie_jar))
|
||||||
|
urllib.request.install_opener(self.opener)
|
||||||
|
|
||||||
|
def get(self, url, headers={}):
|
||||||
|
request = urllib.request.Request(url, headers=headers)
|
||||||
|
return self._request(request)
|
||||||
|
|
||||||
|
def post(self, url, data=None, headers={}):
|
||||||
|
postdata = urllib.parse.urlencode(data).encode()
|
||||||
|
request = urllib.request.Request(url, postdata, headers)
|
||||||
|
return self._request(request)
|
||||||
|
|
||||||
|
def _request(self, request):
|
||||||
|
response = self.opener.open(request)
|
||||||
|
response.status_code = response.getcode()
|
||||||
|
response.data = response.read().decode('utf-8')
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def raw(url):
|
||||||
|
client = UrllibClient()
|
||||||
|
return json_loads(client.get('https://rentry.co/api/raw/{}'.format(url)).data)
|
||||||
|
|
||||||
|
|
||||||
|
def new(url, edit_code, text):
|
||||||
|
client, cookie = UrllibClient(), SimpleCookie()
|
||||||
|
|
||||||
|
cookie.load(vars(client.get('https://rentry.co'))['headers']['Set-Cookie'])
|
||||||
|
csrftoken = cookie['csrftoken'].value
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
'csrfmiddlewaretoken': csrftoken,
|
||||||
|
'url': url,
|
||||||
|
'edit_code': edit_code,
|
||||||
|
'text': text
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_loads(client.post('https://rentry.co/api/new', payload, headers=_headers).data)
|
||||||
|
|
||||||
|
|
||||||
|
def edit(url, edit_code, text):
|
||||||
|
client, cookie = UrllibClient(), SimpleCookie()
|
||||||
|
|
||||||
|
cookie.load(vars(client.get('https://rentry.co'))['headers']['Set-Cookie'])
|
||||||
|
csrftoken = cookie['csrftoken'].value
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
'csrfmiddlewaretoken': csrftoken,
|
||||||
|
'edit_code': edit_code,
|
||||||
|
'text': text
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_loads(client.post('https://rentry.co/api/edit/{}'.format(url), payload, headers=_headers).data)
|
||||||
|
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print('''
|
||||||
|
Usage: rentry {new | edit | raw} {-h | --help} {-u | --url} {-p | --edit-code} text
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
new create a new entry
|
||||||
|
edit edit an existing entry
|
||||||
|
raw get raw markdown text of an existing entry
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-u, --url URL url for the entry, random if not specified
|
||||||
|
-p, --edit-code EDIT-CODE edit code for the entry, random if not specified
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
rentry new 'markdown text' # new entry with random url and edit code
|
||||||
|
rentry new -p pw -u example 'text' # with custom edit code and url
|
||||||
|
rentry edit -p pw -u example 'text' # edit the example entry
|
||||||
|
cat FILE | rentry new # read from FILE and paste it to rentry
|
||||||
|
cat FILE | rentry edit -p pw -u example # read from FILE and edit the example entry
|
||||||
|
rentry raw -u example # get raw markdown text
|
||||||
|
rentry raw -u https://rentry.co/example # -u accepts absolute and relative urls
|
||||||
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
environ.pop('POSIXLY_CORRECT', None)
|
||||||
|
opts, args = getopt.gnu_getopt(sys.argv[1:], "hu:p:", ["help", "url=", "edit-code="])
|
||||||
|
except getopt.GetoptError as e:
|
||||||
|
sys.exit("error: {}".format(e))
|
||||||
|
|
||||||
|
command, url, edit_code, text = None, '', '', None
|
||||||
|
|
||||||
|
for o, a in opts:
|
||||||
|
if o in ("-h", "--help"):
|
||||||
|
usage()
|
||||||
|
sys.exit()
|
||||||
|
elif o in ("-u", "--url"):
|
||||||
|
url = urllib.parse.urlparse(a).path.strip('/')
|
||||||
|
elif o in ("-p", "--edit-code"):
|
||||||
|
edit_code = a
|
||||||
|
|
||||||
|
command = (args[0:1] or [None])[0]
|
||||||
|
command or sys.exit(usage())
|
||||||
|
command in ['new', 'edit', 'raw'] or sys.exit('error: command must be new, edit or raw')
|
||||||
|
|
||||||
|
text = (args[1:2] or [None])[0]
|
||||||
|
if not text and command != 'raw':
|
||||||
|
text = sys.stdin.read().strip()
|
||||||
|
text or sys.exit('error: text is required')
|
||||||
|
|
||||||
|
if command == 'new':
|
||||||
|
response = new(url, edit_code, text)
|
||||||
|
if response['status'] != '200':
|
||||||
|
print('error: {}'.format(response['content']))
|
||||||
|
try:
|
||||||
|
for i in response['errors'].split('.'):
|
||||||
|
i and print(i)
|
||||||
|
sys.exit(1)
|
||||||
|
except:
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print('Url: {}\nEdit code: {}'.format(response['url'], response['edit_code']))
|
||||||
|
|
||||||
|
elif command == 'edit':
|
||||||
|
url or sys.exit('error: url is required')
|
||||||
|
edit_code or sys.exit('error: edit code is required')
|
||||||
|
|
||||||
|
response = edit(url, edit_code, text)
|
||||||
|
if response['status'] != '200':
|
||||||
|
print('error: {}'.format(response['content']))
|
||||||
|
try:
|
||||||
|
for i in response['errors'].split('.'):
|
||||||
|
i and print(i)
|
||||||
|
sys.exit(1)
|
||||||
|
except:
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print('Ok')
|
||||||
|
|
||||||
|
elif command == 'raw':
|
||||||
|
url or sys.exit('error: url is required')
|
||||||
|
response = raw(url)
|
||||||
|
if response['status'] != '200':
|
||||||
|
sys.exit('error: {}'.format(response['content']))
|
||||||
|
print(response['content'])
|
9
pastedb/pastedb01/paste_dict.json
Normal file
9
pastedb/pastedb01/paste_dict.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
{
|
||||||
|
"name": "1680593168-456462",
|
||||||
|
"defau_4e062": {
|
||||||
|
"service": "p.defau.lt",
|
||||||
|
"key": "https://p.defau.lt/?QtZaVCSgOsVMmI1xS_ofqw",
|
||||||
|
"md5sum": "4e062894f660d3c69640129f9fd0a09e"
|
||||||
|
}
|
||||||
|
}
|
0
pastedb/pastedb01/services/__init__.py
Normal file
0
pastedb/pastedb01/services/__init__.py
Normal file
BIN
pastedb/pastedb01/services/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/services/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
pastedb/pastedb01/services/__pycache__/defau.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/services/__pycache__/defau.cpython-310.pyc
Normal file
Binary file not shown.
BIN
pastedb/pastedb01/services/__pycache__/dpaste.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/services/__pycache__/dpaste.cpython-310.pyc
Normal file
Binary file not shown.
BIN
pastedb/pastedb01/services/__pycache__/opendev.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/services/__pycache__/opendev.cpython-310.pyc
Normal file
Binary file not shown.
BIN
pastedb/pastedb01/services/__pycache__/paste2.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/services/__pycache__/paste2.cpython-310.pyc
Normal file
Binary file not shown.
BIN
pastedb/pastedb01/services/__pycache__/pastie.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/services/__pycache__/pastie.cpython-310.pyc
Normal file
Binary file not shown.
BIN
pastedb/pastedb01/services/__pycache__/rentry.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/services/__pycache__/rentry.cpython-310.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
pastedb/pastedb01/services/__pycache__/sprunge.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/services/__pycache__/sprunge.cpython-310.pyc
Normal file
Binary file not shown.
BIN
pastedb/pastedb01/services/__pycache__/termbin.cpython-310.pyc
Normal file
BIN
pastedb/pastedb01/services/__pycache__/termbin.cpython-310.pyc
Normal file
Binary file not shown.
38
pastedb/pastedb01/services/defau.py
Normal file
38
pastedb/pastedb01/services/defau.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
"""
|
||||||
|
This module defines functions to interact with the p.defau.lt service for uploading and retrieving code snippets.
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
- get_service_tag(): Returns a string representing the service tag for p.defau.lt.
|
||||||
|
- upload(data): Uploads a code snippet to p.defau.lt and returns a dictionary containing metadata about the upload.
|
||||||
|
- get(trace): Retrieves the code snippet associated with the provided trace from p.defau.lt.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
URL = 'https://p.defau.lt/submit.php'
|
||||||
|
NAME_PREFIX = 'defau_'
|
||||||
|
|
||||||
|
def get_service_tag():
|
||||||
|
return 'p.defau.lt'
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
json_data = json.dumps(data)
|
||||||
|
md5sum = hashlib.md5(json_data.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(URL, data={'code': json_data})
|
||||||
|
response.raise_for_status()
|
||||||
|
key = response.url
|
||||||
|
name = f"{NAME_PREFIX}{md5sum[:5]}"
|
||||||
|
return {'name': name, 'service': get_service_tag(), 'key': key, 'md5sum': md5sum}
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get(trace):
|
||||||
|
url = trace[key]
|
||||||
|
response = requests.request.get(url)
|
||||||
|
return response.content
|
||||||
|
|
37
pastedb/pastedb01/services/dpaste.py
Normal file
37
pastedb/pastedb01/services/dpaste.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
|
||||||
|
NAME = 'dpaste'
|
||||||
|
|
||||||
|
def get_service_tag():
|
||||||
|
return NAME
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
try:
|
||||||
|
content = json.dumps(data)
|
||||||
|
syntax = 'json'
|
||||||
|
expiry_days = ''
|
||||||
|
|
||||||
|
r = requests.post('https://dpaste.com/api/v2/',
|
||||||
|
data={'content': content,
|
||||||
|
'syntax': syntax,
|
||||||
|
'expiry_days': expiry_days},
|
||||||
|
headers={'User-Agent': 'My Python Project'})
|
||||||
|
|
||||||
|
if r.status_code == 201:
|
||||||
|
dpaste_url = r.headers['Location']
|
||||||
|
#print(f'JSON object uploaded to dpaste.com: {dpaste_url}')
|
||||||
|
md5sum = hashlib.md5(content.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'service': NAME,
|
||||||
|
'key': dpaste_url,
|
||||||
|
'md5sum': md5sum,
|
||||||
|
'name': NAME + '_' + dpaste_url.rsplit('/', 1)[-1]
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
return None
|
||||||
|
|
70
pastedb/pastedb01/services/old_rentry.py
Normal file
70
pastedb/pastedb01/services/old_rentry.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import http.cookiejar
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
from http.cookies import SimpleCookie
|
||||||
|
|
||||||
|
_headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
|
||||||
|
|
||||||
|
class UrllibClient:
|
||||||
|
"""Simple HTTP Session Client, keeps cookies."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.cookie_jar = http.cookiejar.CookieJar()
|
||||||
|
self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.cookie_jar))
|
||||||
|
urllib.request.install_opener(self.opener)
|
||||||
|
|
||||||
|
def get(self, url, headers={}):
|
||||||
|
request = urllib.request.Request(url, headers=headers)
|
||||||
|
return self._request(request)
|
||||||
|
|
||||||
|
def post(self, url, data=None, headers={}):
|
||||||
|
postdata = urllib.parse.urlencode(data).encode()
|
||||||
|
request = urllib.request.Request(url, postdata, headers)
|
||||||
|
return self._request(request)
|
||||||
|
|
||||||
|
def _request(self, request):
|
||||||
|
response = self.opener.open(request)
|
||||||
|
response.status_code = response.getcode()
|
||||||
|
response.data = response.read().decode('utf-8')
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def json_loads(string):
|
||||||
|
try:
|
||||||
|
return json.loads(string)
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
client, cookie = UrllibClient(), SimpleCookie()
|
||||||
|
|
||||||
|
cookie.load(vars(client.get('https://rentry.co'))['headers']['Set-Cookie'])
|
||||||
|
csrftoken = cookie['csrftoken'].value
|
||||||
|
|
||||||
|
json_data = json.dumps(data)
|
||||||
|
md5sum = hashlib.md5(json_data.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
'csrfmiddlewaretoken': csrftoken,
|
||||||
|
'url': md5sum,
|
||||||
|
'edit_code': '',
|
||||||
|
'text': json_data
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post('https://rentry.co/api/new', payload, headers=_headers)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
json_response = json_loads(response.data)
|
||||||
|
return {
|
||||||
|
"service": "rentry",
|
||||||
|
"name": json_response["slug"],
|
||||||
|
"key": f"https://rentry.co/{json_response['slug']}",
|
||||||
|
"md5sum": md5sum
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
44
pastedb/pastedb01/services/opendev.py
Executable file
44
pastedb/pastedb01/services/opendev.py
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
URL = 'https://paste.opendev.org/json/'
|
||||||
|
NAME = 'opendev'
|
||||||
|
|
||||||
|
def get_service_tag():
|
||||||
|
return NAME
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
try:
|
||||||
|
content = json.dumps(data)
|
||||||
|
|
||||||
|
# create JSON payload for new paste
|
||||||
|
payload = {
|
||||||
|
'language': 'text',
|
||||||
|
'code': content,
|
||||||
|
'private': False
|
||||||
|
#'expire': '1day'
|
||||||
|
}
|
||||||
|
|
||||||
|
# send request to create new paste
|
||||||
|
response = requests.post(URL + '?method=pastes.newPaste', json=payload)
|
||||||
|
|
||||||
|
status = response.status_code
|
||||||
|
paste_id = response.json()['data']
|
||||||
|
|
||||||
|
if status == 200:
|
||||||
|
#print(f'JSON object uploaded to dpaste.com: {dpaste_url}')
|
||||||
|
md5sum = hashlib.md5(content.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'service': NAME,
|
||||||
|
'key': URL[:-6],
|
||||||
|
'md5sum': md5sum,
|
||||||
|
'name': NAME + '_' + paste_id + '_' + md5sum[:5]
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
return None
|
||||||
|
# we can get the paste back by:
|
||||||
|
## $ > curl -d '{"paste_id":819463}' -H 'Content-Type: application/json' https://paste.opendev.org/json/?method=pastes.getPaste |jq .data.code
|
20
pastedb/pastedb01/services/paste2.py
Normal file
20
pastedb/pastedb01/services/paste2.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
url = 'https://paste2.org/'
|
||||||
|
|
||||||
|
response = requests.post(url, data={'data': data})
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
# Extract the URL of the uploaded paste from the response
|
||||||
|
paste_url = None
|
||||||
|
for line in response.text.splitlines():
|
||||||
|
if line.startswith('<input type="text" id="paste-url" value="'):
|
||||||
|
paste_url = line.split('"')[3]
|
||||||
|
break
|
||||||
|
|
||||||
|
if paste_url is None:
|
||||||
|
raise ValueError('Could not extract paste URL from response')
|
||||||
|
|
||||||
|
return paste_url
|
||||||
|
|
32
pastedb/pastedb01/services/pastie.py
Normal file
32
pastedb/pastedb01/services/pastie.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
|
URL = 'https://pastie.io/documents'
|
||||||
|
NAME = 'pastie'
|
||||||
|
|
||||||
|
def get_service_tag():
|
||||||
|
return NAME
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
try:
|
||||||
|
json_data = json.dumps(data)
|
||||||
|
md5sum = hashlib.md5(json_data.encode('utf-8')).hexdigest()
|
||||||
|
response = requests.post('https://pastie.io/documents', data=json_data)
|
||||||
|
if response.status_code == 200:
|
||||||
|
key = response.json()['key']
|
||||||
|
pastie_url = f'https://pastie.io/{key}'
|
||||||
|
# print(f'JSON object uploaded to Pastie: {pastie_url}')
|
||||||
|
|
||||||
|
return {
|
||||||
|
"service": NAME,
|
||||||
|
"name": NAME + '_' + key,
|
||||||
|
"key": pastie_url,
|
||||||
|
"md5sum": md5sum
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
return None
|
||||||
|
|
22
pastedb/pastedb01/services/rentry.py
Normal file
22
pastedb/pastedb01/services/rentry.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import subprocess
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
COMMAND = './external/rentry'
|
||||||
|
NAME = 'rentry'
|
||||||
|
|
||||||
|
def get_service_tag():
|
||||||
|
return NAME
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
md5sum = hashlib.md5(json.dumps(data).encode('utf-8')).hexdigest()
|
||||||
|
command = [ COMMAND, 'new', json.dumps(data)]
|
||||||
|
output = subprocess.check_output(command, universal_newlines=True)
|
||||||
|
#print(output)
|
||||||
|
lines = output.strip().split('\n')
|
||||||
|
url = re.search("(?P<url>https?://[^\s]+)", lines[0]).group("url")
|
||||||
|
edit_code = lines[1].split(':')[-1].strip()
|
||||||
|
return {'name': 'rentry_' + edit_code, 'service': 'Rentry', 'key': url, 'md5sum': md5sum}
|
||||||
|
|
45
pastedb/pastedb01/services/sprunge.py
Normal file
45
pastedb/pastedb01/services/sprunge.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import re
|
||||||
|
|
||||||
|
URL = 'http://sprunge.us'
|
||||||
|
NAME = 'sprunge'
|
||||||
|
|
||||||
|
def get_service_tag():
|
||||||
|
return NAME
|
||||||
|
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
try:
|
||||||
|
json_data = json.dumps(data)
|
||||||
|
md5sum = hashlib.md5(json_data.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
# Send the HTTP POST request to the Sprunge API
|
||||||
|
response = requests.post(URL, data={'sprunge': json_data})
|
||||||
|
if response.status_code == 200:
|
||||||
|
|
||||||
|
# Get the URL of the uploaded text from the response body
|
||||||
|
sprunge_url = response.text.strip()
|
||||||
|
|
||||||
|
#print('Uploaded to:', sprunge_url)
|
||||||
|
|
||||||
|
# Use a regular expression to extract the random ID from the URL
|
||||||
|
match = re.match(r'^http://sprunge\.us/(\w+)$', sprunge_url)
|
||||||
|
if match:
|
||||||
|
random_id = match.group(1)
|
||||||
|
#print('Random ID:', random_id)
|
||||||
|
key = "sprunge_" + random_id + '_' + md5sum[:5]
|
||||||
|
else:
|
||||||
|
print('Invalid Sprunge URL:', sprunge_url)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"service": "sprunge",
|
||||||
|
"name": key,
|
||||||
|
"key": sprunge_url,
|
||||||
|
"md5sum": md5sum
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
return None
|
26
pastedb/pastedb01/services/termbin.py
Normal file
26
pastedb/pastedb01/services/termbin.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import subprocess
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
|
def generate_name():
|
||||||
|
"""Generate a random name for the paste"""
|
||||||
|
ts = int(time.time())
|
||||||
|
rand_str = ''.join(random.choices(string.ascii_lowercase, k=5))
|
||||||
|
name = f"termbin-{ts}-{rand_str}"
|
||||||
|
return name
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
"""Upload the data to termbin.com"""
|
||||||
|
name = generate_name()
|
||||||
|
try:
|
||||||
|
cmd = f"echo '{data}' | nc termbin.com 9999"
|
||||||
|
response = subprocess.check_output(cmd, shell=True, timeout=5).decode()
|
||||||
|
url = f"https://termbin.com/{name}"
|
||||||
|
md5sum = hashlib.md5(data.encode('utf-8')).hexdigest()
|
||||||
|
return {'service': 'termbin', 'key': url, 'md5sum': md5sum}
|
||||||
|
except (subprocess.CalledProcessError, subprocess.TimeoutExpired) as e:
|
||||||
|
print(f"Upload failed with error: {e}")
|
||||||
|
return None
|
||||||
|
|
24
pastedb/pastedb01/upload.py
Normal file
24
pastedb/pastedb01/upload.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from typing import Dict
|
||||||
|
from services import pastie, dpaste, rentry, defau, sprunge, opendev
|
||||||
|
from data.data import add_data, save_data, set_encryption_key
|
||||||
|
|
||||||
|
|
||||||
|
def upload_and_store(data: Dict):
|
||||||
|
# set encryption key if necessary
|
||||||
|
set_encryption_key(b'upload_id=upload_and_store(my_da')
|
||||||
|
|
||||||
|
traces = {}
|
||||||
|
for service in [pastie, dpaste, rentry, defau, sprunge, opendev]:
|
||||||
|
result = service.upload(data)
|
||||||
|
if result:
|
||||||
|
traces[result['name']] = result['key']
|
||||||
|
add_data(service.get_service_tag(), result['name'], result['md5sum'])
|
||||||
|
save_data('data.json', data, key=b'my_key123')
|
||||||
|
return traces
|
||||||
|
|
||||||
|
my_data = {"name": "Sashenka", "age": 26, "country": "Anguilla"}
|
||||||
|
|
||||||
|
upload_trace = upload_and_store(my_data)
|
||||||
|
|
||||||
|
print('trace: ', upload_trace)
|
||||||
|
|
161
pastedb/rentry
Executable file
161
pastedb/rentry
Executable file
@ -0,0 +1,161 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import getopt
|
||||||
|
import http.cookiejar
|
||||||
|
import sys
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
from http.cookies import SimpleCookie
|
||||||
|
from json import loads as json_loads
|
||||||
|
from os import environ
|
||||||
|
|
||||||
|
_headers = {"Referer": 'https://rentry.co'}
|
||||||
|
|
||||||
|
|
||||||
|
class UrllibClient:
|
||||||
|
"""Simple HTTP Session Client, keeps cookies."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.cookie_jar = http.cookiejar.CookieJar()
|
||||||
|
self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.cookie_jar))
|
||||||
|
urllib.request.install_opener(self.opener)
|
||||||
|
|
||||||
|
def get(self, url, headers={}):
|
||||||
|
request = urllib.request.Request(url, headers=headers)
|
||||||
|
return self._request(request)
|
||||||
|
|
||||||
|
def post(self, url, data=None, headers={}):
|
||||||
|
postdata = urllib.parse.urlencode(data).encode()
|
||||||
|
request = urllib.request.Request(url, postdata, headers)
|
||||||
|
return self._request(request)
|
||||||
|
|
||||||
|
def _request(self, request):
|
||||||
|
response = self.opener.open(request)
|
||||||
|
response.status_code = response.getcode()
|
||||||
|
response.data = response.read().decode('utf-8')
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def raw(url):
|
||||||
|
client = UrllibClient()
|
||||||
|
return json_loads(client.get('https://rentry.co/api/raw/{}'.format(url)).data)
|
||||||
|
|
||||||
|
|
||||||
|
def new(url, edit_code, text):
|
||||||
|
client, cookie = UrllibClient(), SimpleCookie()
|
||||||
|
|
||||||
|
cookie.load(vars(client.get('https://rentry.co'))['headers']['Set-Cookie'])
|
||||||
|
csrftoken = cookie['csrftoken'].value
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
'csrfmiddlewaretoken': csrftoken,
|
||||||
|
'url': url,
|
||||||
|
'edit_code': edit_code,
|
||||||
|
'text': text
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_loads(client.post('https://rentry.co/api/new', payload, headers=_headers).data)
|
||||||
|
|
||||||
|
|
||||||
|
def edit(url, edit_code, text):
|
||||||
|
client, cookie = UrllibClient(), SimpleCookie()
|
||||||
|
|
||||||
|
cookie.load(vars(client.get('https://rentry.co'))['headers']['Set-Cookie'])
|
||||||
|
csrftoken = cookie['csrftoken'].value
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
'csrfmiddlewaretoken': csrftoken,
|
||||||
|
'edit_code': edit_code,
|
||||||
|
'text': text
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_loads(client.post('https://rentry.co/api/edit/{}'.format(url), payload, headers=_headers).data)
|
||||||
|
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print('''
|
||||||
|
Usage: rentry {new | edit | raw} {-h | --help} {-u | --url} {-p | --edit-code} text
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
new create a new entry
|
||||||
|
edit edit an existing entry
|
||||||
|
raw get raw markdown text of an existing entry
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-u, --url URL url for the entry, random if not specified
|
||||||
|
-p, --edit-code EDIT-CODE edit code for the entry, random if not specified
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
rentry new 'markdown text' # new entry with random url and edit code
|
||||||
|
rentry new -p pw -u example 'text' # with custom edit code and url
|
||||||
|
rentry edit -p pw -u example 'text' # edit the example entry
|
||||||
|
cat FILE | rentry new # read from FILE and paste it to rentry
|
||||||
|
cat FILE | rentry edit -p pw -u example # read from FILE and edit the example entry
|
||||||
|
rentry raw -u example # get raw markdown text
|
||||||
|
rentry raw -u https://rentry.co/example # -u accepts absolute and relative urls
|
||||||
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
environ.pop('POSIXLY_CORRECT', None)
|
||||||
|
opts, args = getopt.gnu_getopt(sys.argv[1:], "hu:p:", ["help", "url=", "edit-code="])
|
||||||
|
except getopt.GetoptError as e:
|
||||||
|
sys.exit("error: {}".format(e))
|
||||||
|
|
||||||
|
command, url, edit_code, text = None, '', '', None
|
||||||
|
|
||||||
|
for o, a in opts:
|
||||||
|
if o in ("-h", "--help"):
|
||||||
|
usage()
|
||||||
|
sys.exit()
|
||||||
|
elif o in ("-u", "--url"):
|
||||||
|
url = urllib.parse.urlparse(a).path.strip('/')
|
||||||
|
elif o in ("-p", "--edit-code"):
|
||||||
|
edit_code = a
|
||||||
|
|
||||||
|
command = (args[0:1] or [None])[0]
|
||||||
|
command or sys.exit(usage())
|
||||||
|
command in ['new', 'edit', 'raw'] or sys.exit('error: command must be new, edit or raw')
|
||||||
|
|
||||||
|
text = (args[1:2] or [None])[0]
|
||||||
|
if not text and command != 'raw':
|
||||||
|
text = sys.stdin.read().strip()
|
||||||
|
text or sys.exit('error: text is required')
|
||||||
|
|
||||||
|
if command == 'new':
|
||||||
|
response = new(url, edit_code, text)
|
||||||
|
if response['status'] != '200':
|
||||||
|
print('error: {}'.format(response['content']))
|
||||||
|
try:
|
||||||
|
for i in response['errors'].split('.'):
|
||||||
|
i and print(i)
|
||||||
|
sys.exit(1)
|
||||||
|
except:
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print('Url: {}\nEdit code: {}'.format(response['url'], response['edit_code']))
|
||||||
|
|
||||||
|
elif command == 'edit':
|
||||||
|
url or sys.exit('error: url is required')
|
||||||
|
edit_code or sys.exit('error: edit code is required')
|
||||||
|
|
||||||
|
response = edit(url, edit_code, text)
|
||||||
|
if response['status'] != '200':
|
||||||
|
print('error: {}'.format(response['content']))
|
||||||
|
try:
|
||||||
|
for i in response['errors'].split('.'):
|
||||||
|
i and print(i)
|
||||||
|
sys.exit(1)
|
||||||
|
except:
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print('Ok')
|
||||||
|
|
||||||
|
elif command == 'raw':
|
||||||
|
url or sys.exit('error: url is required')
|
||||||
|
response = raw(url)
|
||||||
|
if response['status'] != '200':
|
||||||
|
sys.exit('error: {}'.format(response['content']))
|
||||||
|
print(response['content'])
|
34
pastedb/rentry_upload.py
Normal file
34
pastedb/rentry_upload.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def upload(data):
|
||||||
|
json_data = json.dumps(data)
|
||||||
|
md5sum = hashlib.md5(json_data.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
# Run rentry client as subprocess
|
||||||
|
p = subprocess.Popen(
|
||||||
|
['./services/rentry', 'new', {json_data}],
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE
|
||||||
|
)
|
||||||
|
|
||||||
|
# Send JSON data to rentry client
|
||||||
|
stdout, stderr = p.communicate(json_data.encode('utf-8'))
|
||||||
|
|
||||||
|
if p.returncode != 0:
|
||||||
|
# Rentry client failed
|
||||||
|
print(f"Error running rentry client: {stderr.decode('utf-8')}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Parse JSON response from rentry client
|
||||||
|
json_response = json.loads(stdout.decode('utf-8'))
|
||||||
|
|
||||||
|
return {
|
||||||
|
"service": "rentry",
|
||||||
|
"name": json_response["slug"],
|
||||||
|
"key": f"https://rentry.co/{json_response['slug']}",
|
||||||
|
"md5sum": md5sum
|
||||||
|
}
|
||||||
|
|
25
webpage-stuff/button-example.html
Normal file
25
webpage-stuff/button-example.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
textarea{
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
function buttonPressed() {
|
||||||
|
var inputText = document.getElementById("inputText").value;
|
||||||
|
var textBox = document.getElementById("myTextBox");
|
||||||
|
textBox.value += inputText + "\n";
|
||||||
|
textBox.scrollTop = textBox.scrollHeight;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<textarea id="myTextBox" rows="4" cols="50" style="overflow:auto"></textarea>
|
||||||
|
<br>
|
||||||
|
<input type="text" id="inputText">
|
||||||
|
<button onclick="buttonPressed()">Press me</button>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user