Skip to content
This repository was archived by the owner on Dec 21, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
backend/ipfs/data
backend/ipfs/ipfs_fuse
backend/ipfs/ipns_fuse
backend/bitcoin-core
.idea
env.docker
docker-compose.yml
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,6 @@ cp -r ~/.nym/clients/docker-client nym-data/clients

* `backend/` manage the websockets connections and DB
* [Frontend](https://github.com/notrustverify/pastenym-frontend) web application
* [CLI](https://github.com/notrustverify/pastenym-cli) CLI application to interact with pastenym without the frontend
* [CLI](https://github.com/notrustverify/pastenym-cli) application to interact with pastenym without the frontend
* `nym-client/` store the configuration,keys for the nym-client
* `resources/` store img or files for documentation
3 changes: 2 additions & 1 deletion backend/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ websocket-client = "1.4.1"
rel = "*"
requests = "*"
py-cid = "*"

python-bitcoinrpc = "*"
dateparser = "*"

[dev-packages]

Expand Down
260 changes: 247 additions & 13 deletions backend/Pipfile.lock

Large diffs are not rendered by default.

92 changes: 92 additions & 0 deletions backend/cron.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import json
import time
import traceback
from bitcoinrpc.authproxy import AuthServiceProxy
import db
import utils

TIME_EXECUTION_TIME_MINUTES = 0


class Cron:

def __init__(self):
self.db = db.BaseModel()
self.firstRun = True

timestampNow = time.time()
self.lastExecutionTime = timestampNow

# test if connection to Bitcoin Core is working
self.bitcoinCoreWorking = False

if Cron.bitcoinExpirationEnabled():
self.rpc_connection = AuthServiceProxy(
f"http://{utils.BITCOIN_USER}:{utils.BITCOIN_PASSWORD}@{utils.BITCOIN_RPC_URL}:{utils.BITCOIN_RPC_URL_PORT}")
self.lastExecutionHeight = Cron.getCurrentHeight()

if self.lastExecutionHeight > 0:
self.bitcoinCoreWorking = True

if not(self.bitcoinCoreWorking):
print("Connection to Bitcoin Core is not working. Paste height expiration is disabled")


def executeCron(self):

if self.firstRun:
print("First run delete job")
print(f"Number paste time deleted: {self.deleteExpiredTimePaste()}")

if Cron.bitcoinExpirationEnabled() and self.bitcoinCoreWorking:
print(f"Number paste height deleted: {self.deleteExpiredHeightPaste(self.lastExecutionHeight)}")

self.firstRun = False
return

timestampNow = time.time()

# only execute delete paste every 1 minute
if self.lastExecutionTime <= timestampNow - TIME_EXECUTION_TIME_MINUTES * 60:
print(f"Number paste time deleted: {self.deleteExpiredTimePaste()}")
self.lastExecutionTime = timestampNow

if Cron.bitcoinExpirationEnabled() and self.bitcoinCoreWorking:

heightNow = Cron.getCurrentHeight()

if self.lastExecutionHeight <= heightNow:
print(f"Number paste height deleted: {self.deleteExpiredHeightPaste(heightNow)}")
self.lastExecutionHeight = heightNow

def deleteExpiredTimePaste(self):
return self.db.deletePasteExpirationTime(Cron.getCurrentTime())

def deleteExpiredHeightPaste(self, heightNow):
if heightNow > 0:
return self.db.deletePasteExpirationHeight(heightNow)
else:
print("error with current height, cannot remove the paste")
return 0

@staticmethod
def getCurrentHeight():

try:
rpc_connection = AuthServiceProxy(
f"http://{utils.BITCOIN_USER}:{utils.BITCOIN_PASSWORD}@{utils.BITCOIN_RPC_URL}:{utils.BITCOIN_RPC_URL_PORT}")
if rpc_connection.getblockchaininfo()['initialblockdownload']:
print("Be careful fullnode is not synced")
numBlocks = rpc_connection.getblockcount()
return numBlocks
except Exception:
traceback.print_exc()
return 0

@staticmethod
def getCurrentTime():
return time.time()

@staticmethod
def bitcoinExpirationEnabled():
return True if utils.BITCOIN_RPC_URL is not None else False
34 changes: 32 additions & 2 deletions backend/db.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import time
import traceback
from datetime import datetime

Expand Down Expand Up @@ -36,7 +37,7 @@ def idExists(self, id):
finally:
self.close()

def insertText(self, text, url_id, enc_params_b64, burn_view=0,private=True, burn=False, ipfs=False):
def insertText(self, text, url_id, enc_params_b64, burn_view=0,private=True, burn=False, ipfs=False,expiration_time=None, expiration_height=None):
self.connect()

try:
Expand All @@ -48,7 +49,9 @@ def insertText(self, text, url_id, enc_params_b64, burn_view=0,private=True, bur
url_id=url_id,
is_private=private,
is_burn=burn,
burn_view=burn_view
burn_view=burn_view,
expiration_time=expiration_time,
expiration_height=expiration_height
).execute()

return list(Text.select().where(Text.id == idInsert).dicts())
Expand Down Expand Up @@ -103,6 +106,31 @@ def getTextByUrlId(self, url_id):
finally:
self.close()

def deletePasteExpirationTime(self,currentTimestamp):
try:
with database.atomic():

return Text.delete().where(Text.expiration_time <= currentTimestamp).execute()

except (IntegrityError, DoesNotExist) as e:
logHandler.exception(e)
return False
finally:
self.close()

def deletePasteExpirationHeight(self, currentHeight):
try:
with database.atomic():

return Text.delete().where(Text.expiration_height <= currentHeight).execute()

except (IntegrityError, DoesNotExist) as e:
logHandler.exception(e)
return False
finally:
self.close()



class Text(BaseModel):
class Meta:
Expand All @@ -114,6 +142,8 @@ class Meta:
# Setting url_id as index allows faster operations
url_id = TextField(index=True)
expiration_time = TimestampField(null=True)
expiration_height = TimestampField(null=True)

author = TextField(null=True)
# If not null, means that 'text' field is encrypted with password
encryption_params_b64 = TextField(null=True)
Expand Down
1 change: 1 addition & 0 deletions backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import db
from os.path import exists
import ipfsHandler
import cron

if __name__ == '__main__':

Expand Down
33 changes: 28 additions & 5 deletions backend/pasteNym.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from datetime import datetime

import cron
import db
import sys
import utils
import html
import json
import base64
import ipfsHandler
from utils import isBase64
import dateparser


class PasteNym:
Expand Down Expand Up @@ -40,12 +40,34 @@ def newText(self, data):
if data.get('burn') and type(data.get('burn')) == bool:
burn = data.get('burn')

if data.get('burn_view') and type(data.get('burn_view')) == int and 0 < data.get('burn_view') <= 10000 :
if data.get('burn_view') and type(data.get('burn_view')) == int and 0 < data.get('burn_view') <= 10000:
burn_view = data.get('burn_view')
else:
burn_view = 1


expiration_time = None
if data.get('expiration_time') and type(data.get('expiration_time')) == str:
rel_expiration_time = data.get('expiration_time')
try:
# transform relative time from string to timestamp add in keyword to specify in future
expiration_time = dateparser.parse("in " + rel_expiration_time).timestamp()
except Exception as e:
print(f"Parsing time error, set to 0, {e}")
expiration_time = 0

expiration_height = None
if data.get('expiration_height') and type(
data.get('expiration_height')) == int and data.get('expiration_height') > 0:
if utils.BITCOIN_RPC_URL:
currentActual = cron.Cron.getCurrentHeight()
if currentActual > 0:
expiration_height = data.get('expiration_height') + currentActual
else:
print("error: with current height")
return None
else:
print("error: Bitcoin block not working")
return None

# by default the pastes are not uploaded to IPFS
ipfs = False
Expand Down Expand Up @@ -88,7 +110,8 @@ def newText(self, data):
while self.db.idExists(urlId) is not None:
urlId = utils.generateRandomString(self.idLength)

return self.db.insertText(html.escape(text), urlId, encParamsB64, burn_view, private, burn, ipfs)
return self.db.insertText(html.escape(text), urlId, encParamsB64, burn_view, private, burn, ipfs,
expiration_time, expiration_height)


except (KeyError, AttributeError) as e:
Expand Down
Loading