renaming folder structure
@ -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 |
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.
|