2
0
mirror of https://github.com/ComradCollective/Comrad synced 2024-11-01 21:40:32 +00:00

hooking up feed to db

This commit is contained in:
quadrismegistus 2020-08-12 08:40:44 +01:00
parent c0bba5f91f
commit cf2f38e4e0
5 changed files with 365 additions and 4 deletions

View File

@ -125,8 +125,8 @@ class MainApp(MDApp):
self.root.change_screen('login')
log(self.username)
else:
self.root.post_id=190
self.root.change_screen('view')
# self.root.post_id=190
self.root.change_screen('feed')
return self.root
def load_store(self):
@ -263,6 +263,13 @@ class MainApp(MDApp):
return jsond
def get_posts(self):
with self.get_session() as sess:
with sess.get(self.api+'/posts') as r:
log(r.text)
jsond=r.json()
return jsond['posts']
return []
def get_image(self, img_src):
# is there an image?

View File

@ -5,6 +5,7 @@ from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.card import MDCard, MDSeparator
from kivy.uix.scrollview import ScrollView
from screens.base import ProtectedScreen
from kivy.properties import ListProperty
from main import log
import os
from kivy.app import App
@ -121,7 +122,32 @@ class PostCard(MDCard):
class FeedScreen(ProtectedScreen):
posts = ListProperty()
def on_pre_enter(self):
# log('ids:' +str(self.ids.post_carousel.ids))
for post in self.posts:
log('post: '+str(post))
self.ids.post_carousel.remove_widget(post)
i=0
lim=25
for i,post in enumerate(reversed(self.app.get_posts())):
#if ln.startswith('@') or ln.startswith('RT '): continue
#i+=1
if i>lim: break
#post = Post(title=f'Marx Zuckerberg', content=ln.strip())
post_obj = PostCard(
author='Marx Zuckerberg',
title='',
img_src=post.get('img_src',''),
content=post.get('content',''))
log(post)
self.posts.append(post_obj)
self.ids.post_carousel.add_widget(post_obj)
def on_pre_enter_test(self):
i=0
lim=5
with open('tweets.txt') as f:

View File

@ -0,0 +1,104 @@
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)
# test_models()

View File

@ -0,0 +1,220 @@
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)

View File

@ -11,7 +11,7 @@ from werkzeug.utils import secure_filename
# works better with tor?
import json
jsonify = json.dumps
jsonify = str
# jsonify = str
# Start server
@ -196,9 +196,13 @@ def get_posts(name=None):
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 = [to_data(post) for post in posts]
data = {"posts":[to_data(post) for post in posts]}
# print(data)
return jsonify(data)