renaming folder structure

p2p2
quadrismegistus 4 years ago
parent 952ba59368
commit df7a4de897

10
.gitignore vendored

@ -1,11 +1,7 @@
__pycache__
client/examples/*
client/komrade.json
uploads
uploads/*
uploads/*/*
client/cache
client/log.txt
app/komrade.json
app/cache
app/log.txt
venv
.vscode
sto.dat

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Before

Width:  |  Height:  |  Size: 491 KiB

After

Width:  |  Height:  |  Size: 491 KiB

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Before

Width:  |  Height:  |  Size: 7.1 MiB

After

Width:  |  Height:  |  Size: 7.1 MiB

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Before

Width:  |  Height:  |  Size: 923 KiB

After

Width:  |  Height:  |  Size: 923 KiB

Before

Width:  |  Height:  |  Size: 491 KiB

After

Width:  |  Height:  |  Size: 491 KiB

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 224 KiB

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 246 KiB

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

@ -36,6 +36,8 @@ from kivy.core.window import Window
from kivy.core.text import LabelBase
import shutil,sys
from kivy.uix.image import Image
import sys
sys.path.append("..") # Adds higher directory to python modules path.
from p2p import p2p,crypto,api
Window.size = WINDOW_SIZE
@ -145,8 +147,7 @@ class MainApp(MDApp):
self.load_store()
# self.boot_kad()
from p2p.api import Api
self.api = Api(app_storage=self.store)
self.api = api.Api(app_storage=self.store)
self.username=''
# bind

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -1 +0,0 @@
SSL_DISABLE=True

@ -1,10 +0,0 @@
Traceback (most recent call last):
File "/home/ryan/github/Komrade/venv/lib/python3.6/site-packages/twisted/application/app.py", line 312, in runReactorWithLogging
reactor.run()
File "/home/ryan/github/Komrade/venv/lib/python3.6/site-packages/twisted/internet/base.py", line 1282, in run
self.startRunning(installSignalHandlers=installSignalHandlers)
File "/home/ryan/github/Komrade/venv/lib/python3.6/site-packages/twisted/internet/base.py", line 1262, in startRunning
ReactorBase.startRunning(self)
File "/home/ryan/github/Komrade/venv/lib/python3.6/site-packages/twisted/internet/base.py", line 765, in startRunning
raise error.ReactorNotRestartable()
twisted.internet.error.ReactorNotRestartable

@ -1,129 +0,0 @@
from neomodel import *
NEO4J_USERNAME='neo4j'
NEO4J_PASSWORD='driveyourplowoverthebonesofthedead'
NEO4J_SERVER='localhost'
NEO4J_PORT=7687
config.DATABASE_URL = f'bolt://{NEO4J_USERNAME}:{NEO4J_PASSWORD}@{NEO4J_SERVER}:{NEO4J_PORT}' # default
config.ENCRYPTED_CONNECTION = False
# exit()
# G = Graph(password='drive your plow over the bones of the dead')
# Nodes = NodeMatcher(G)
# Edges = RelationshipMatcher(G)
class Media(StructuredNode):
uid=UniqueIdProperty()
ext=StringProperty()
@property
def filename(self):
return self.uid[:3]+'/'+self.uid[3:]+self.ext
@property
def data(self):
return {'uid':self.uid, 'ext':self.ext, 'filename':self.filename}
class Person(StructuredNode):
uid = UniqueIdProperty()
name = StringProperty(unique_index=True, required=True)
name_irl = StringProperty()
passkey = StringProperty()
wrote = RelationshipTo('Post','WROTE')
follows = RelationshipTo('Person','FOLLOWS')
followed_by = RelationshipFrom('Person','FOLLOWS')
located_in = RelationshipTo('Place','LOCATED_IN')
in_group = RelationshipTo('Group','IN_GROUP')
based_in = RelationshipTo('Place','LOCATED')
has_avatar = RelationshipTo('Media','HAS_MEDIA')
@property
def img_src_avatar(self):
avatar = self.has_avatar.first()
if avatar:
return avatar.filename
return ''
@property
def data(self):
img_avatar
dx={'uid':self.uid, 'name':self.name, 'name_irl':self.name_irl,
'img_src_avatar':self.img_src_avatar}
class Post(StructuredNode):
# properties
uid = UniqueIdProperty()
content = StringProperty()
has_media = RelationshipTo('Media','HAS_MEDIA')
# relations
written_by = RelationshipFrom('Person','WROTE')
located_in = RelationshipTo('Place','LOCATED')
@property
def author(self):
written_by = self.written_by
if not written_by: return None
person=written_by[0]
person.passkey=None
return person
@property
def img_src(self):
print(dir(self.has_media))
if self.has_media:
media = self.has_media[0]
return media.filename
return None
@property
def data(self):
return {'uid':self.uid, 'content':self.content, 'img_src':self.img_src}
class Place(StructuredNode):
# properties
uid = UniqueIdProperty()
name = StringProperty(unique_index=True)
posted_in = RelationshipFrom('Post','LOCATED')
based_in = RelationshipFrom('Person','LOCATED')
@property
def data(self):
return {'uid':self.uid, 'name':self.name}
class Group(StructuredNode):
uid = UniqueIdProperty()
name = StringProperty(unique_index=True)
motto = StringProperty()
mission = StringProperty()
has_members = RelationshipFrom('Person','IN_GROUP')
@property
def data(self):
return {'uid':self.uid, 'name':self.name, 'motto':self.motto, 'mission':self.mission}
def test_models():
jim = Person(name='Jim').save()
post = Post(content='woooo').save()
jim.wrote.connect(post)
print(dir(post))
print(jim.uid, post.uid)
print(list(post.written_by.all()))
print(post.author)
if __name__ == '__main__':
test_models()

@ -1,102 +0,0 @@
from py2neo import *
from py2neo.ogm import *
G = Graph(password='drive your plow over the bones of the dead')
Nodes = NodeMatcher(G)
Edges = RelationshipMatcher(G)
class MyGraphObject(GraphObject):
@property
def data(self):
return dict(self.__ogm__.node)
class Person(MyGraphObject):
__primarykey__ = 'name'
name = Property()
name_irl = Property()
passkey = Property()
posts = RelatedTo('Post','WROTE')
follows = RelatedTo('Person','FOLLOWS')
followers = RelatedFrom('Person','FOLLOWS')
based_in = RelatedTo('Place','BASED_IN')
groups = RelatedTo('Group','IN_GROUP')
avatar = RelatedTo('Media','HAS_MEDIA')
class Post(MyGraphObject):
# properties
title = Property()
content = Property()
img_src = Property()
# relations
author = RelatedFrom('Person','WROTE')
location = RelatedTo('Place','BASED_IN')
@property
def data(self):
dx=dict(self.__ogm__.node)
authors=list(self.author)
locations=list(self.location)
dx['author']=authors[0].name if authors else ''
dx['location']=locations[0].name if locations else ''
return dx
class Place(MyGraphObject):
# properties
__primarykey__ = 'name'
name = Property()
# relations
citizens = RelatedFrom('Person','BASED_IN')
class Group(MyGraphObject):
# properties
__primarykey__ = 'name'
name = Property()
motto = Property()
mission = Property()
# relations
members = RelatedFrom('Person','IN_GROUP')
def test_models():
x = Person(); x.name='MrX'
y = Person(); y.name='MrY'
p1 = Post(); p1.title='Post 1'; p1.content='Hello world!'
p2 = Post(); p2.title='Post 2'; p2.content='Hello world!!!'
p3 = Post(); p3.title='Post 3'; p3.content='Hello world!!!!!!!!!!!!'
x.follows.add(y)
x.posts.add(p1)
y.posts.add(p2)
G.push(y)
y.posts.add(p3)
g1=Group(); g1.name='BlocBloc'
c1=Place(); c1.name='Utopia'
c2=Place(); c2.name='Dystopia'
x.based_in.add(c1)
y.based_in.add(c2)
x.groups.add(g1)
y.groups.add(g1)
for a in [x,y,p1,p2,p3,g1,c1,c2]: G.push(a)
if __name__ == '__main__':
test_models()

@ -1,233 +0,0 @@
import os,time
from pathlib import Path
from models import *
from werkzeug.utils import secure_filename
from werkzeug.security import generate_password_hash,check_password_hash
from twisted.internet import defer
from twisted.internet.defer import ensureDeferred
from twisted.logger import Logger
log = Logger()
from klein import Klein
import json
jsonify = json.dumps
# Start server
app = Klein()
app.config = {}
app.config["DEBUG"] = True
app.config['SECRET_KEY'] = 'Bring out number weight & measure in a year of dearth'
# socketio = SocketIO(app)
app.config['UPLOAD_DIR'] = 'uploads/'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
## errors
@app.route('/')
def home(request): return jsonify({'error':'404 go home friend'})
# Api Functions
def read_request_json(request):
json_str = str(request.content.read().decode('utf-8'))
# print('json_str',type(json_str),json_str)
return json.loads(json_str)
def get_person(name):
print('sleeping...')
time.sleep(10)
person = Person.nodes.get_or_none(name=name)
print('returning?')
return person
## LOGIN
@app.route('/api/login',methods=['POST'])
def login(request):
data=read_request_json(request)
print('data',data)
name=data.get('name','')
passkey=data.get('passkey','')
if not (name and passkey):
request.setResponseCode(400)
return jsonify({'error':'Login failed'})
# print('sleeping...')
# time.sleep(10)
# person = yield Person.nodes.get_or_none(name=name)
# print('sleeping...?')
person = get_person(name)
if person is None:
request.setResponseCode(401)
return jsonify({'error':'User exists'})
real_passkey = person.passkey
if not check_password_hash(real_passkey, passkey):
request.setResponseCode(401)
return jsonify({'error':'Login failed'})
request.setResponseCode(200)
return jsonify({'success':'Login success'})
@app.route('/api/register',methods=['POST'])
def register(request):
data=read_request_json(request)
name=data.get('name','')
passkey=data.get('passkey','')
if not (name and passkey):
request.setResponseCode(400)
return {'error':'Register failed'},status.HTTP_400_BAD_REQUEST
person = Person.nodes.get_or_none(name=name)
if person is not None:
request.setResponseCode(401)
return {'error':'User exists'}
passkey = generate_password_hash(passkey)
person = Person(name=name,passkey=passkey).save()
print('REGISTERED!',data)
return {'success':'Account created', 'username':name},status.HTTP_200_OK
## CREATE
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/api/upload',methods=['POST'])
def upload(request):
files = request.files
# check if the post request has the file part
if 'file' not in request.files:
return {'error':'No file found'},status.HTTP_204_NO_CONTENT
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
print('filename!',file.filename)
if file.filename == '':
return {'error':'No filename'},status.HTTP_206_PARTIAL_CONTENT
if file and allowed_file(file.filename):
print('uploading file...')
#prefix,filename = get_random_filename(file.filename) #secure_filename(file.filename)
#odir = os.path.join(app.config['UPLOAD_DIR'], os.path.dirname(filename))
#if not os.path.exists(odir):
ext = os.path.splitext(file.filename)[-1]
media = Media(ext=ext).save()
uid = media.uid
filename = media.filename
prefix,fn=filename.split('/')
folder = os.path.join(app.config['UPLOAD_DIR'], prefix)
if not os.path.exists(folder): os.makedirs(folder)
file.save(os.path.join(folder, fn))
#return redirect(url_for('uploaded_file', filename=filename))
return {'media_uid':uid, 'filename':filename}, status.HTTP_200_OK
return {'error':'Upload failed'},status.HTTP_406_NOT_ACCEPTABLE
@app.route('/api/post',methods=['POST'])
@app.route('/api/post/<post_id>',methods=['GET'])
def post(request,post_id=None):
if request.method == 'POST':
# get data
data=read_request_json(request)
print('POST /api/post:',data)
# make post
post = Post(content=data.get('content','')).save()
# attach author
name = data.get('username')
if name:
author = Person.nodes.get_or_none(name=name)
author.wrote.connect(post)
# attach media
media_uid=data.get('media_uid')
if media_uid:
media=Media.nodes.get_or_none(uid=media_uid)
post.has_media.connect(media)
# return
post_id=post.uid
print('created new post!',post_id)
return {'post_id':post_id},status.HTTP_200_OK
print('got post id!',post_id)
post = Post.nodes.get_or_none(uid=post_id)
if not post: return {},status.HTTP_204_NO_CONTENT
return post.data,status.HTTP_200_OK
@app.route('/api/download/<prefix>/<filename>',methods=['GET'])
def download(request, prefix, filename):
filedir = os.path.join(app.config['UPLOAD_DIR'], prefix)
print(filedir, filename)
return send_from_directory(filedir, filename)
### READ
@app.route('/api/followers/<name>')
def get_followers(request, name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.followers]
return jsonify(data)
@app.route('/api/followers/<name>')
def get_follows(request, name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.follows]
return jsonify(data)
@app.route('/api/posts')
@app.route('/api/posts/<name>')
def get_posts(request, name=None):
if name:
person = Person.nodes.get_or_none(name=name)
data = [p.data for p in person.wrote.all] if person is not None else []
else:
data = [p.data for p in Post.nodes.all()]
# print(data)
return jsonify({'posts':data})
@app.route('/api/post/<int:id>')
def get_post(request, id=None):
post = Post.match(G, int(id)).first()
data = post.data
return jsonify(data)
if __name__=='__main__':
app.run(host='0.0.0.0', port=5555)
# socketio.run(app, host='0.0.0.0', port=5000)

@ -1,204 +0,0 @@
import flask,os
from flask import request, jsonify, send_from_directory
from pathlib import Path
from models import *
from flask_api import FlaskAPI, status, exceptions
from werkzeug.security import generate_password_hash,check_password_hash
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename
# works better with tor?
import json
jsonify = json.dumps
# jsonify = str
# Start server
app = flask.Flask(__name__)
app.config["DEBUG"] = True
app.config['UPLOAD_DIR'] = 'uploads/'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
@app.route('/')
def home(): return {'error':'404 go home friend'}
# Api Functions
## LOGIN
@app.route('/api/login',methods=['POST'])
def login():
data=request.json
name=data.get('name','')
passkey=data.get('passkey','')
if not (name and passkey):
return {'error':'Login failed'},status.HTTP_400_BAD_REQUEST
person = Person.nodes.get_or_none(name=name)
if person is None:
return {'error':'User exists'},status.HTTP_401_UNAUTHORIZED
real_passkey = person.passkey
if not check_password_hash(real_passkey, passkey):
return {'error':'Login failed'},status.HTTP_401_UNAUTHORIZED
return {'success':'Login success'},status.HTTP_200_OK
@app.route('/api/register',methods=['POST'])
def register():
data=request.json
name=data.get('name','')
passkey=data.get('passkey','')
if not (name and passkey):
return {'error':'Register failed'},status.HTTP_400_BAD_REQUEST
person = Person.nodes.get_or_none(name=name)
if person is not None:
return {'error':'User exists'},status.HTTP_401_UNAUTHORIZED
passkey = generate_password_hash(passkey)
person = Person(name=name,passkey=passkey).save()
print('REGISTERED!',data)
return {'success':'Account created', 'username':name},status.HTTP_200_OK
## CREATE
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def get_random_filename(filename):
import uuid
fn=uuid.uuid4().hex
return (fn[:3],fn[3:]+os.path.splitext(filename)[-1])
@app.route('/api/upload',methods=['POST'])
def upload():
files = request.files
# check if the post request has the file part
if 'file' not in request.files:
return {'error':'No file found'},status.HTTP_204_NO_CONTENT
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
print('filename!',file.filename)
if file.filename == '':
return {'error':'No filename'},status.HTTP_206_PARTIAL_CONTENT
if file and allowed_file(file.filename):
print('uploading file...')
#prefix,filename = get_random_filename(file.filename) #secure_filename(file.filename)
#odir = os.path.join(app.config['UPLOAD_DIR'], os.path.dirname(filename))
#if not os.path.exists(odir):
ext = os.path.splitext(file.filename)[-1]
media = Media(ext=ext).save()
uid = media.uid
filename = media.filename
prefix,fn=filename.split('/')
folder = os.path.join(app.config['UPLOAD_DIR'], prefix)
if not os.path.exists(folder): os.makedirs(folder)
file.save(os.path.join(folder, fn))
#return redirect(url_for('uploaded_file', filename=filename))
return {'media_uid':uid, 'filename':filename}, status.HTTP_200_OK
return {'error':'Upload failed'},status.HTTP_406_NOT_ACCEPTABLE
@app.route('/api/post',methods=['POST'])
@app.route('/api/post/<post_id>',methods=['GET'])
def post(post_id=None):
if request.method == 'POST':
# get data
data=request.json
print('POST /api/post:',data)
# make post
post = Post(content=data.get('content','')).save()
# attach author
name = data.get('username')
if name:
author = Person.nodes.get_or_none(name=name)
author.wrote.connect(post)
# attach media
media_uid=data.get('media_uid')
if media_uid:
media=Media.nodes.get_or_none(uid=media_uid)
post.has_media.connect(media)
# return
post_id=post.uid
print('created new post!',post_id)
return {'post_id':post_id},status.HTTP_200_OK
print('got post id!',post_id)
post = Post.nodes.get_or_none(uid=post_id)
if not post: return {},status.HTTP_204_NO_CONTENT
return post.data,status.HTTP_200_OK
@app.route('/api/download/<prefix>/<filename>',methods=['GET'])
def download(prefix, filename):
filedir = os.path.join(app.config['UPLOAD_DIR'], prefix)
print(filedir, filename)
return send_from_directory(filedir, filename)
### READ
@app.route('/api/followers/<name>')
def get_followers(name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.followers]
return jsonify(data)
@app.route('/api/followers/<name>')
def get_follows(name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.follows]
return jsonify(data)
@app.route('/api/posts')
@app.route('/api/posts/<name>')
def get_posts(name=None):
if name:
person = Person.nodes.get_or_none(name=name)
data = [p.data for p in person.wrote.all] if person is not None else []
else:
data = [p.data for p in Post.nodes.all()]
# print(data)
return jsonify({'posts':data})
@app.route('/api/post/<int:id>')
def get_post(id=None):
post = Post.match(G, int(id)).first()
data = post.data
return jsonify(data)
app.run(host='0.0.0.0', port=5555)

@ -1,220 +0,0 @@
import flask,os
from flask import request, jsonify, send_from_directory
from pathlib import Path
from models import *
from flask_api import FlaskAPI, status, exceptions
from werkzeug.security import generate_password_hash,check_password_hash
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename
# works better with tor?
import json
jsonify = json.dumps
# jsonify = str
# Start server
app = flask.Flask(__name__)
app.config["DEBUG"] = True
app.config['UPLOAD_DIR'] = 'uploads/'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
@app.route('/')
def home(): return {'error':'404 go home friend'}
# Api Functions
## LOGIN
@app.route('/api/login',methods=['POST'])
def login():
data=request.json
name=data.get('name','')
passkey=data.get('passkey','')
if not (name and passkey):
return {'error':'Login failed'},status.HTTP_400_BAD_REQUEST
persons = list(Person.match(G,name))
if not persons:
return {'error':'Login failed'},status.HTTP_401_UNAUTHORIZED
person = persons[0]
real_passkey = person.passkey
if not check_password_hash(real_passkey, passkey):
return {'error':'Login failed'},status.HTTP_401_UNAUTHORIZED
return {'success':'Login success'},status.HTTP_200_OK
@app.route('/api/register',methods=['POST'])
def register():
data=request.json
name=data.get('name','')
passkey=data.get('passkey','')
if not (name and passkey):
return {'error':'Register failed'},status.HTTP_400_BAD_REQUEST
person = list(Person.match(G,name))
if person:
return {'error':'User exists'},status.HTTP_401_UNAUTHORIZED
passkey = generate_password_hash(passkey)
person = Person()
person.name = name
person.passkey = passkey
G.push(person)
print('REGISTERED!',data)
return {'success':'Account created', 'username':name, 'passkey':passkey},status.HTTP_200_OK
## CREATE
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def get_random_filename(filename):
import uuid
fn=uuid.uuid4().hex
return (fn[:3],fn[3:]+os.path.splitext(filename)[-1])
@app.route('/api/upload',methods=['POST'])
def upload_file():
files = request.files
# check if the post request has the file part
if 'file' not in request.files:
return {'error':'No file found'},status.HTTP_204_NO_CONTENT
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
print('filename!',file.filename)
if file.filename == '':
return {'error':'No filename'},status.HTTP_206_PARTIAL_CONTENT
if file and allowed_file(file.filename):
print('uploading file...')
prefix,filename = get_random_filename(file.filename) #secure_filename(file.filename)
#odir = os.path.join(app.config['UPLOAD_DIR'], os.path.dirname(filename))
#if not os.path.exists(odir):
folder = os.path.join(app.config['UPLOAD_DIR'], prefix)
if not os.path.exists(folder): os.mkdir(folder)
file.save(os.path.join(folder, filename))
#return redirect(url_for('uploaded_file', filename=filename))
return {'filename':prefix+'/'+filename}, status.HTTP_200_OK
return {'error':'Upload failed'},status.HTTP_406_NOT_ACCEPTABLE
@app.route('/api/post',methods=['POST'])
@app.route('/api/post/<int:post_id>',methods=['GET'])
def post(post_id=None):
if request.method == 'POST':
# get data
data=request.json
print('POST /api/post:',data)
# make post
post = Post()
post.content = data.get('content','')
post.img_src = data.get('img_src','')
G.push(post)
# attach to author
username=data.get('username','')
author = Person.match(G, username).first()
print('author?', author)
author.posts.add(post)
# post.author.add(author)
G.push(author)
# return
post_id=str(post.__ogm__.node.identity)
print('created new post!',post_id)
return {'post_id':post_id},status.HTTP_200_OK
print('got post id!',post_id)
posts = list(Post.match(G,post_id))
if not posts:
return {},status.HTTP_204_NO_CONTENT
post=posts[0]
print(post.data)
return post.data,status.HTTP_200_OK
@app.route('/api/download/<prefix>/<filename>',methods=['GET'])
def download(prefix, filename):
filedir = os.path.join(app.config['UPLOAD_DIR'], prefix)
print(filedir, filename)
return send_from_directory(filedir, filename)
### READ
@app.route('/api/followers/<name>')
def get_followers(name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.followers]
return jsonify(data)
@app.route('/api/followers/<name>')
def get_follows(name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.follows]
return jsonify(data)
@app.route('/api/posts')
@app.route('/api/posts/<name>')
def get_posts(name=None):
if name:
person = Person.match(G, name).first()
data = [p.data for p in person.posts]
else:
# data=[]
# def handle_row(row):
# node = row[0]
# data+=[node.data] # do something with `node` here
# G.match
# G.cypher.execute("START z=node(*) RETURN z", row_handler=handle_row)
matcher = NodeMatcher(G)
posts = matcher.match('Post')
# posts = Post.match(G).where("_.content = '*'")
def to_data(post):
d=dict(post)
d['id']=post.identity
# authors=list(post.author)
# locations=list(post.location)
# d['author']=authors[0].name if authors else ''
# d['location']=locations[0].name if locations else ''
return d
data = {"posts":[to_data(post) for post in posts]}
# print(data)
return jsonify(data)
@app.route('/api/post/<int:id>')
def get_post(id=None):
post = Post.match(G, int(id)).first()
data = post.data
return jsonify(data)
app.run(host='0.0.0.0', port=5555)

@ -1,130 +0,0 @@
from neomodel import *
NEO4J_USERNAME='neo4j'
NEO4J_PASSWORD='driveyourplowoverthebonesofthedead'
NEO4J_SERVER='localhost'
NEO4J_PORT=7687
config.DATABASE_URL = f'bolt://{NEO4J_USERNAME}:{NEO4J_PASSWORD}@{NEO4J_SERVER}:{NEO4J_PORT}' # default
config.ENCRYPTED_CONNECTION = False
# exit()
# G = Graph(password='drive your plow over the bones of the dead')
# Nodes = NodeMatcher(G)
# Edges = RelationshipMatcher(G)
class Media(StructuredNode):
uid=UniqueIdProperty()
ext=StringProperty()
@property
def filename(self):
return self.uid[:3]+'/'+self.uid[3:]+self.ext
@property
def data(self):
return {'uid':self.uid, 'ext':self.ext, 'filename':self.filename}
class Person(StructuredNode):
uid = UniqueIdProperty()
name = StringProperty(unique_index=True, required=True)
name_irl = StringProperty()
passkey = StringProperty()
wrote = RelationshipTo('Post','WROTE')
follows = RelationshipTo('Person','FOLLOWS')
followed_by = RelationshipFrom('Person','FOLLOWS')
located_in = RelationshipTo('Place','LOCATED_IN')
in_group = RelationshipTo('Group','IN_GROUP')
based_in = RelationshipTo('Place','LOCATED')
has_avatar = RelationshipTo('Media','HAS_MEDIA')
@property
def img_src_avatar(self):
avatar = self.has_avatar.first()
if avatar:
return avatar.filename
return ''
@property
def data(self):
img_avatar
dx={'uid':self.uid, 'name':self.name, 'name_irl':self.name_irl,
'img_src_avatar':self.img_src_avatar}
class Post(StructuredNode):
# properties
uid = UniqueIdProperty()
content = StringProperty()
timestamp = FloatProperty(index=True)
# relations
has_media = RelationshipTo('Media','HAS_MEDIA')
written_by = RelationshipFrom('Person','WROTE')
located_in = RelationshipTo('Place','LOCATED')
@property
def author(self):
written_by = self.written_by
if not written_by: return None
person=written_by[0]
person.passkey=None
return person
@property
def img_src(self):
# print(dir(self.has_media))
if self.has_media:
media = self.has_media[0]
return media.filename
return None
@property
def data(self):
return {'uid':self.uid, 'content':self.content, 'img_src':self.img_src, 'timestamp':self.timestamp, 'author':self.author.name}
class Place(StructuredNode):
# properties
uid = UniqueIdProperty()
name = StringProperty(unique_index=True)
posted_in = RelationshipFrom('Post','LOCATED')
based_in = RelationshipFrom('Person','LOCATED')
@property
def data(self):
return {'uid':self.uid, 'name':self.name}
class Group(StructuredNode):
uid = UniqueIdProperty()
name = StringProperty(unique_index=True)
motto = StringProperty()
mission = StringProperty()
has_members = RelationshipFrom('Person','IN_GROUP')
@property
def data(self):
return {'uid':self.uid, 'name':self.name, 'motto':self.motto, 'mission':self.mission}
def test_models():
jim = Person(name='Jim').save()
post = Post(content='woooo').save()
jim.wrote.connect(post)
print(dir(post))
print(jim.uid, post.uid)
print(list(post.written_by.all()))
print(post.author)
if __name__ == '__main__':
test_models()

@ -1,5 +0,0 @@
from gevent.pywsgi import WSGIServer
from server import app
http_server = WSGIServer(('', 5555), app)
http_server.serve_forever()

@ -1,3 +0,0 @@
# gunicorn -w 4 -b 0.0.0.0:5555 server:app
# python run.py
python server.py

@ -1,212 +0,0 @@
import flask,os,time
from flask import request, jsonify, send_from_directory
from pathlib import Path
from models import *
from flask_api import FlaskAPI, status, exceptions
from werkzeug.security import generate_password_hash,check_password_hash
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename
# works better with tor?
import json
jsonify = json.dumps
# jsonify = str
# Start server
app = flask.Flask(__name__)
app.config["DEBUG"] = True
app.config['UPLOAD_DIR'] = 'uploads/'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
@app.route('/')
def home(): return {'error':'404 go home friend'}
# Api Functions
## LOGIN
@app.route('/api/login',methods=['POST'])
def login():
data=request.json
name=data.get('name','')
passkey=data.get('passkey','')
if not (name and passkey):
return {'error':'Login failed'},status.HTTP_400_BAD_REQUEST
person = Person.nodes.get_or_none(name=name)
if person is None:
return {'error':'User exists'},status.HTTP_401_UNAUTHORIZED
real_passkey = person.passkey
if not check_password_hash(real_passkey, passkey):
return {'error':'Login failed'},status.HTTP_401_UNAUTHORIZED
return {'success':'Login success'},status.HTTP_200_OK
@app.route('/api/register',methods=['POST'])
def register():
data=request.json
name=data.get('name','')
passkey=data.get('passkey','')
if not (name and passkey):
return {'error':'Register failed'},status.HTTP_400_BAD_REQUEST
person = Person.nodes.get_or_none(name=name)
if person is not None:
return {'error':'User exists'},status.HTTP_401_UNAUTHORIZED
passkey = generate_password_hash(passkey)
person = Person(name=name,passkey=passkey).save()
print('REGISTERED!',data)
return {'success':'Account created', 'username':name},status.HTTP_200_OK
## CREATE
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def get_random_filename(filename):
import uuid
fn=uuid.uuid4().hex
return (fn[:3],fn[3:]+os.path.splitext(filename)[-1])
@app.route('/api/upload',methods=['POST'])
def upload():
files = request.files
# check if the post request has the file part
if 'file' not in request.files:
return {'error':'No file found'},status.HTTP_204_NO_CONTENT
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
print('filename!',file.filename)
if file.filename == '':
return {'error':'No filename'},status.HTTP_206_PARTIAL_CONTENT
if file and allowed_file(file.filename):
print('uploading file...')
#prefix,filename = get_random_filename(file.filename) #secure_filename(file.filename)
#odir = os.path.join(app.config['UPLOAD_DIR'], os.path.dirname(filename))
#if not os.path.exists(odir):
ext = os.path.splitext(file.filename)[-1]
media = Media(ext=ext).save()
uid = media.uid
filename = media.filename
prefix,fn=filename.split('/')
folder = os.path.join(app.config['UPLOAD_DIR'], prefix)
if not os.path.exists(folder): os.makedirs(folder)
file.save(os.path.join(folder, fn))
#return redirect(url_for('uploaded_file', filename=filename))
return {'media_uid':uid, 'filename':filename}, status.HTTP_200_OK
return {'error':'Upload failed'},status.HTTP_406_NOT_ACCEPTABLE
@app.route('/api/post',methods=['POST'])
@app.route('/api/post/<post_id>',methods=['GET'])
def post(post_id=None):
if request.method == 'POST':
# get data
data=request.json
print('POST /api/post:',data)
# make post
post = Post(content=data.get('content',''), timestamp=data.get('timestamp')).save()
# attach author
name = data.get('username')
if name:
author = Person.nodes.get_or_none(name=name)
author.wrote.connect(post)
# attach media
media_uid=data.get('media_uid')
if media_uid:
media=Media.nodes.get_or_none(uid=media_uid)
post.has_media.connect(media)
# return
post_id=post.uid
print('created new post!',post_id)
return {'post_id':post_id},status.HTTP_200_OK
print('got post id!',post_id)
post = Post.nodes.get_or_none(uid=post_id)
if not post: return {},status.HTTP_204_NO_CONTENT
return post.data,status.HTTP_200_OK
@app.route('/api/download/<prefix>/<filename>',methods=['GET'])
def download(prefix, filename):
filedir = os.path.join(app.config['UPLOAD_DIR'], prefix)
print(filedir, filename)
return send_from_directory(filedir, filename)
### READ
@app.route('/api/followers/<name>')
def get_followers(name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.followers]
return jsonify(data)
@app.route('/api/followers/<name>')
def get_follows(name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.follows]
return jsonify(data)
@app.route('/api/posts')
@app.route('/api/posts/<name>')
def get_posts(name=None):
if name:
person = Person.nodes.get_or_none(name=name)
data = [p.data for p in person.wrote.all()] if person is not None else []
else:
data = [p.data for p in Post.nodes.order_by('-timestamp')]
# print(data)
return jsonify({'posts':data})
@app.route('/api/post/<int:id>')
def get_post(id=None):
post = Post.match(G, int(id)).first()
data = post.data
return jsonify(data)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5555)
# socketio.run(app,host='0.0.0.0', port=5555)
# from gevent import pywsgi
# from geventwebsocket.handler import WebSocketHandler
# server = pywsgi.WSGIServer(('', 5555), app, handler_class=WebSocketHandler)
# server.serve_forever()

@ -1,6 +0,0 @@
2020-08-12T14:13:34+0100 [twisted.logger._global#warn] Warning: primary log target selected twice at </home/ryan/github/Komrade/venv/lib/python3.6/site-packages/twisted/application/app.py:213> - previously selected at </home/ryan/github/Komrade/venv/lib/python3.6/site-packages/twisted/python/log.py:214>. Remove one of the calls to beginLoggingTo.
2020-08-12T14:13:34+0100 [twisted.scripts._twistd_unix.UnixAppLogger#info] twistd 20.3.0 (/home/ryan/github/Komrade/venv/bin/python 3.6.9) starting up.
2020-08-12T14:13:34+0100 [twisted.scripts._twistd_unix.UnixAppLogger#info] reactor class: twisted.internet.epollreactor.EPollReactor.
2020-08-12T14:13:34+0100 [-] Site starting on 8080
2020-08-12T14:13:34+0100 [twisted.web.server.Site#info] Starting factory <twisted.web.server.Site object at 0x7f91e00ba400>
2020-08-12T14:13:34+0100 [twisted.scripts._twistd_unix.UnixAppLogger#info] Server Shut Down.
Loading…
Cancel
Save