Compare commits
No commits in common. "582844bacf3321fc530b830fb628108a4d6774e6" and "32d3e2dfe12a2a95773e0781e14568abfa8b9e41" have entirely different histories.
582844bacf
...
32d3e2dfe1
@ -1,26 +0,0 @@
|
|||||||
#!/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.
@ -1,20 +0,0 @@
|
|||||||
|
|
||||||
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
|
|
@ -1,27 +0,0 @@
|
|||||||
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()
|
|
@ -1,12 +0,0 @@
|
|||||||
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()
|
|
@ -1,2 +0,0 @@
|
|||||||
requests==2.25.1
|
|
||||||
matplotlib==3.6.2
|
|
100
chat.html
100
chat.html
@ -1,100 +0,0 @@
|
|||||||
<!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>
|
|
||||||
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,36 +0,0 @@
|
|||||||
#!/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()
|
|
@ -1,35 +0,0 @@
|
|||||||
#!/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()
|
|
@ -1,27 +0,0 @@
|
|||||||
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"}
|
|
@ -1,377 +0,0 @@
|
|||||||
#!/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()
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
|||||||
#!/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}')
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
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}")
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
|||||||
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')
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
|||||||
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))
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
|||||||
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()
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
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)
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
|||||||
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')
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
|||||||
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}")
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
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
|
|
@ -1,5 +0,0 @@
|
|||||||
import requests
|
|
||||||
|
|
||||||
data = {"data": 'print("Hello!")'}
|
|
||||||
r = requests.post("https://zerobin.net/?paste", data=data)
|
|
||||||
print(f"URL: {r.text}")
|
|
@ -1,331 +0,0 @@
|
|||||||
#!/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())
|
|
@ -1,69 +0,0 @@
|
|||||||
#!/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()
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
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}")
|
|
@ -1,26 +0,0 @@
|
|||||||
#!/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)
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
#!/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
|
|
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "1680462198-dxx",
|
|
||||||
"pastie": {
|
|
||||||
"service": "pastie",
|
|
||||||
"key": "jpllic",
|
|
||||||
"md5sum": "5e87ba1e0d151a399c0418343842b94d"
|
|
||||||
},
|
|
||||||
"ogqfsh": {
|
|
||||||
"url": "https://pastie.io/ogqfsh",
|
|
||||||
"service": "Pastie"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
ed566cf8f839c936bfd5582f1af6aa7d0d8457fcdd3c421d4424eedb41d5868155a6e04a291c4add0a2ec88a287d0371605d8ff9be6cbf2ba91d67097e39c0333cbf57515d9072d998d1dee110f3ecab
|
|
Binary file not shown.
Binary file not shown.
@ -1,122 +0,0 @@
|
|||||||
"""
|
|
||||||
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."}'
|
|
Binary file not shown.
161
pastedb/pastedb01/external/rentry
vendored
161
pastedb/pastedb01/external/rentry
vendored
@ -1,161 +0,0 @@
|
|||||||
#!/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'])
|
|
@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
{
|
|
||||||
"name": "1680593168-456462",
|
|
||||||
"defau_4e062": {
|
|
||||||
"service": "p.defau.lt",
|
|
||||||
"key": "https://p.defau.lt/?QtZaVCSgOsVMmI1xS_ofqw",
|
|
||||||
"md5sum": "4e062894f660d3c69640129f9fd0a09e"
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,38 +0,0 @@
|
|||||||
"""
|
|
||||||
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
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
|||||||
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
|
|
@ -1,20 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
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}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
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
|
|
@ -1,26 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
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
161
pastedb/rentry
@ -1,161 +0,0 @@
|
|||||||
#!/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'])
|
|
@ -1,34 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
|||||||
<!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