got progress loading etc done

p2p
quadrismegistus 4 years ago
parent 03cc320ad2
commit 1a193bb7eb

@ -0,0 +1,333 @@
## CONFIG
# change this to your external ip address for your server
#(needs to be external to allow tor routing)
SERVER_ADDR = '128.232.229.63:5555'
# imports
from kivy.uix.screenmanager import Screen,ScreenManager
from kivymd.app import MDApp
from kivymd.uix.button import MDFillRoundFlatButton, MDIconButton
from kivymd.uix.toolbar import MDToolbar
from kivymd.uix.screen import MDScreen
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.theming import ThemeManager
from kivy.properties import ObjectProperty,ListProperty
import time,os
from collections import OrderedDict
from functools import partial
from kivy.uix.screenmanager import NoTransition
from kivymd.uix.label import MDLabel
from kivy.uix.widget import Widget
from kivymd.uix.list import OneLineListItem
from kivymd.uix.card import MDCard, MDSeparator
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.metrics import dp
from kivy.properties import NumericProperty
from kivymd.uix.list import * #MDList, ILeftBody, IRightBody, ThreeLineAvatarListItem, TwoLineAvatarListItem, BaseListItem, ImageLeftWidget
from kivy.uix.image import Image, AsyncImage
import requests,json
from kivy.storage.jsonstore import JsonStore
from kivy.core.window import Window
from kivy.core.text import LabelBase
import shutil
Window.size = (640, 1136) #(2.65 * 200, 5.45 * 200)
def log(x):
with open('log.txt','a+') as of:
of.write(str(x)+'\n')
class MyLayout(MDBoxLayout):
scr_mngr = ObjectProperty(None)
post_id = ObjectProperty()
def change_screen(self, screen, *args):
self.scr_mngr.current = screen
def view_post(self,post_id):
self.post_id=post_id
self.change_screen('view')
class MyBoxLayout(MDBoxLayout): pass
class MyLabel(MDLabel): pass
#### LOGIN
def get_tor_proxy_session():
session = requests.session()
# Tor uses the 9050 port as the default socks port
session.proxies = {'http': 'socks5://127.0.0.1:9050',
'https': 'socks5://127.0.0.1:9050'}
return session
def get_async_tor_proxy_session():
from requests_futures.sessions import FuturesSession
session = FuturesSession()
# Tor uses the 9050 port as the default socks port
session.proxies = {'http': 'socks5://127.0.0.1:9050',
'https': 'socks5://127.0.0.1:9050'}
return session
def get_tor_python_session():
from torpy.http.requests import TorRequests
with TorRequests() as tor_requests:
with tor_requests.get_session() as s:
return s
class MainApp(MDApp):
title = 'Komrade'
#api = 'http://localhost:5555/api'
api = 'http://%s/api' % SERVER_ADDR
#api = 'http://komrades.net:5555/api'
logged_in=False
store = JsonStore('komrade.json')
login_expiry = 60 * 60 * 24 * 7 # once a week
#login_expiry = 5 # 5 seconds
def get_session(self):
# return get_async_tor_proxy_session()
return get_tor_proxy_session()
#return get_tor_python_session()
def get_username(self):
if hasattr(self,'username'): return self.username
self.load_store()
if hasattr(self,'username'): return self.username
return ''
def build(self):
self.username=''
# bind
global app,root
app = self
#self.username = self.store.get('userd').get('username')
self.load_store()
self.root = root = Builder.load_file('root.kv')
# edit logo
logo=root.ids.toolbar.ids.label_title
logo.font_name='assets/Strengthen.ttf'
logo.font_size='58dp'
logo.pos_hint={'center_y':0.43}
# icons
icons=root.ids.toolbar.ids.right_actions.children
for icon in icons:
#log(dir(icon))
#icon.icon='android' #user_font_size='200sp'
icon.font_size='58dp'
icon.user_font_size='58dp'
icon.width='58dp'
icon.size_hint=(None,None)
icon.height='58dp'
if not self.is_logged_in():
self.root.change_screen('login')
log(self.username)
else:
# self.root.post_id=190
self.root.change_screen('post')
return self.root
def load_store(self):
if not self.store.exists('user'): return
userd=self.store.get('user')
if not userd: userd={}
self.logged_in_when = userd.get('logged_in_when')
self.username = userd.get('username','')
def is_logged_in(self,just_check_timestamp=True, use_caching=True):
if self.logged_in: return True
if not use_caching: return False
###
if not self.store.exists('user'): return False
userd=self.store.get('user')
if not userd: userd={}
if userd.get('logged_in'):
un=userd.get('username')
timestamp=userd.get('logged_in_when')
# just a time check
if timestamp and just_check_timestamp:
if time.time() - timestamp < self.login_expiry:
self.logged_in=True
#self.username=un
return True
return False
def save_login(self,un):
self.logged_in=True
self.username=un
# self.store.put('username',un)
self.store.put('user',username=un,logged_in=True,logged_in_when=time.time())
self.root.change_screen('feed')
def login(self,un=None,pw=None):
url = self.api+'/login'
with self.get_session() as sess:
#res = requests.post(url, json={'name':un, 'passkey':pw})
res = sess.post(url, json={'name':un, 'passkey':pw})
log(res.text)
if res.status_code==200:
data=res.json()
self.save_login(un)
return True
else:
# self.root.ids.login_status.text=res.text
return False
def register(self,un,pw):
url = self.api+'/register'
with self.get_session() as sess:
#res = requests.post(url, json={'name':un, 'passkey':pw})
res = sess.post(url, json={'name':un, 'passkey':pw})
if res.status_code==200:
self.save_login(un)
else:
pass
#self.root.ids.login_status.text=res.text
def post(self, content='', img_src=[], logger=None):
timestamp=time.time()
log('content: '+str(content))
log('img_src: '+str(img_src))
logger = logger if logger is not None else log
jsond = {'content':str(content)}
# upload?
filename=img_src[0] if img_src and os.path.exists(img_src[0]) else ''
url_upload=self.api+'/upload'
url_post = self.api+'/post'
server_filename=''
media_uid=None
with self.get_session() as sess:
if filename:
log(filename)
# copy file to cache
logger('Uploading file') #self.root.ids.add_post_screen.ids.post_status.text='Uploading file'
with sess.post(url_upload,files={'file':open(filename,'rb')}) as r1:
if r1.status_code==200:
rdata1 = r1.json()
server_filename = rdata1.get('filename','')
media_uid=rdata1.get('media_uid')
if server_filename:
logger('File uploaded')
# pre-cache
cache_filename = os.path.join('cache','img',server_filename)
cache_filedir = os.path.dirname(cache_filename)
if not os.path.exists(cache_filedir): os.makedirs(cache_filedir)
shutil.copyfile(filename,cache_filename)
# add post
logger('Creating post')
jsond={'img_src':server_filename, 'content':content, 'username':self.username, 'media_uid':media_uid, 'timestamp':timestamp}
# post
with sess.post(url_post, json=jsond) as r2:
log('got back from post: ' + r2.text)
rdata2 = r2.json()
post_id = rdata2.get('post_id',None)
if post_id:
logger('Post created')
#self.root.view_post(post_id)
self.root.change_screen('feed')
# pre-cache
with open(os.path.join('cache','json',str(post_id)+'.json'),'w') as of:
json.dump(jsond, of)
def get_post(self,post_id):
# get json from cache?
ofn_json = os.path.join('cache','json',str(post_id)+'.json')
if os.path.exists(ofn_json):
with open(ofn_json) as f:
jsond = json.load(f)
else:
with self.get_session() as sess:
with sess.get(self.api+'/post/'+str(post_id)) as r:
jsond = r.json()
# cache it!
with open(ofn_json,'w') as of:
json.dump(jsond, of)
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_posts_async(self):
result=[]
with self.get_session() as sess:
futures = [sess.get(self.api+'/posts')]
for future in as_completed(futures):
log('second?')
r=future.result()
log(r.text)
jsond=r.json()
result=jsond['posts']
log('first?')
return result
def get_image(self, img_src):
# is there an image?
if not img_src: return
# is it cached?
ofn_image = os.path.join('cache','img',img_src)
if not os.path.exists(ofn_image):
# create dir?
ofn_image_dir = os.path.split(ofn_image)[0]
if not os.path.exists(ofn_image_dir): os.makedirs(ofn_image_dir)
log('getting image!')
with self.get_session() as sess:
with sess.get(self.api+'/download/'+img_src,stream=True) as r:
with open(ofn_image,'wb') as of:
shutil.copyfileobj(r.raw, of)
return ofn_image
if __name__ == '__main__':
App = MainApp()
App.run()

@ -2,6 +2,7 @@
# change this to your external ip address for your server
#(needs to be external to allow tor routing)
SERVER_ADDR = '128.232.229.63:5555'
DEFAULT_SCREEN='feed'
# imports
from kivy.uix.screenmanager import Screen,ScreenManager
@ -145,7 +146,7 @@ class MainApp(MDApp):
log(self.username)
else:
# self.root.post_id=190
self.root.change_screen('feed')
self.root.change_screen(DEFAULT_SCREEN)
return self.root
def load_store(self):
@ -180,7 +181,7 @@ class MainApp(MDApp):
self.logged_in=True
self.username=un
# self.store.put('username',un)
# self.store.put('user',username=un,logged_in=True,logged_in_when=time.time())
self.store.put('user',username=un,logged_in=True,logged_in_when=time.time())
self.root.change_screen('feed')
@ -212,59 +213,57 @@ class MainApp(MDApp):
pass
#self.root.ids.login_status.text=res.text
def post(self, content='', img_src=[]):
log('content: '+str(content))
log('img_src: '+str(img_src))
jsond = {'content':str(content)}
# upload?
filename=img_src[0] if img_src and os.path.exists(img_src[0]) else ''
def upload(self,orig_img_src):
url_upload=self.api+'/upload'
url_post = self.api+'/post'
filename=orig_img_src[0] if orig_img_src and os.path.exists(orig_img_src[0]) else ''
if not filename: return
server_filename=''
media_uid=None
with self.get_session() as sess:
if filename:
log(filename)
# copy file to cache
self.root.ids.add_post_screen.ids.post_status.text='Uploading file'
with sess.post(url_upload,files={'file':open(filename,'rb')}) as r1:
if r1.status_code==200:
rdata1 = r1.json()
server_filename = rdata1.get('filename','')
media_uid=rdata1.get('media_uid')
if server_filename:
self.root.ids.add_post_screen.ids.post_status.text='File uploaded'
# pre-cache
cache_filename = os.path.join('cache','img',server_filename)
cache_filedir = os.path.dirname(cache_filename)
if not os.path.exists(cache_filedir): os.makedirs(cache_filedir)
shutil.copyfile(filename,cache_filename)
# add post
self.root.ids.add_post_screen.ids.post_status.text='Creating post'
jsond={'img_src':server_filename, 'content':content, 'username':self.username, 'media_uid':media_uid}
with sess.post(url_upload,files={'file':open(filename,'rb')}) as r1:
if r1.status_code==200:
rdata1 = r1.json()
server_filename = rdata1.get('filename','')
media_uid=rdata1.get('media_uid')
if server_filename:
# pre-cache
cache_filename = os.path.join('cache','img',server_filename)
cache_filedir = os.path.dirname(cache_filename)
if not os.path.exists(cache_filedir): os.makedirs(cache_filedir)
shutil.copyfile(filename,cache_filename)
return {'cache_filename':cache_filename, 'media_uid':media_uid, 'server_filename':server_filename}
def post(self, content='', media_uid=None):
timestamp=time.time()
jsond = {'content':str(content),'media_uid':media_uid,
'username':self.username, 'timestamp':timestamp}
url_post = self.api+'/post'
with self.get_session() as sess:
# post
with sess.post(url_post, json=jsond) as r2:
log('got back from post: ' + r2.text)
rdata2 = r2.json()
post_id = rdata2.get('post_id',None)
if post_id:
self.root.ids.add_post_screen.ids.post_status.text='Post created'
self.root.view_post(post_id)
# pre-cache
with open(os.path.join('cache','json',str(post_id)+'.json'),'w') as of:
cache_dir = os.path.join('cache','json',post_id[:3])
cache_fnfn = os.path.join(cache_dir,post_id[3:]+'.json')
if not os.path.exists(cache_dir): os.makedirs(cache_dir)
with open(cache_fnfn,'w') as of:
json.dump(jsond, of)
#self.root.view_post(post_id)
self.root.change_screen('feed')
return {'post_id':post_id}

@ -54,7 +54,7 @@
Color:
rgb: 0,0,0,1
Line:
width: 7
width: 12
rectangle: (self.x, self.y, self.width, self.height)
@ -108,6 +108,22 @@
halign: 'left'
padding: ('10dp','0dp')
<PostTimestampLabel>:
id: post_timestamp_label
text: ''
pos_hint: {'center_y':0.5, 'center_x':0.5}
# font_size:'100dp'
# font_style:'H5'
# font_style: 'custom'
#font_name: "Strengthen"
# height: '400'
size_hint_y: None
# size_hint_x: 100
text_color:1,0,0,1
theme_text_color: 'Custom'
halign: 'right'
padding: ('10dp','0dp')

@ -7,9 +7,12 @@ from kivy.uix.scrollview import ScrollView
from screens.base import ProtectedScreen
from kivy.properties import ListProperty
from main import log
import os
import os,time
from datetime import datetime
from kivy.app import App
### POST CODE
class PostTitle(MDLabel): pass
@ -28,6 +31,7 @@ class PostAuthorLayout(MDBoxLayout): pass
class PostImageLayout(MDBoxLayout): pass
class PostAuthorLabel(MDLabel):
def __init__(self,**kwargs):
super().__init__(**kwargs)
@ -35,6 +39,14 @@ class PostAuthorLabel(MDLabel):
self.bind(texture_size=self.setter('size'))
self.font_name='assets/overpass-mono-regular.otf'
pass
class PostTimestampLabel(MDLabel):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.bind(width=lambda s, w: s.setter('text_size')(s, (w, None)))
self.bind(texture_size=self.setter('size'))
self.font_name='assets/overpass-mono-regular.otf'
class PostAuthorAvatar(AsyncImage): pass
class PostLayout(MDBoxLayout): pass
@ -42,14 +54,15 @@ class PostLayout(MDBoxLayout): pass
class PostScrollView(ScrollView): pass
class PostCard(MDCard):
def __init__(self, author = None, title = None, img_src = None, content = None):
def __init__(self, data):
super().__init__()
self.author = author
self.title = title
self.img_src = img_src if img_src else ''
self.cache_img_src = os.path.join('cache','img',img_src) if img_src else ''
log('DATA: '+str(data))
self.author = data.get('author','[Anonymous]')
self.img_src = data.get('img_src','')
self.cache_img_src = os.path.join('cache','img',self.img_src) if self.img_src else ''
self.img_loaded = os.path.exists(self.cache_img_src)
self.content = content
self.content = data.get('content','')
self.timestamp = data.get('timestamp',None)
self.bind(minimum_height=self.setter('height'))
# pieces
@ -59,6 +72,15 @@ class PostCard(MDCard):
author_avatar = PostAuthorAvatar(source='avatar.jpg') #self.img_src)
author_section_layout.add_widget(author_avatar)
author_section_layout.add_widget(author_label)
# timestamp
timestr=''
log(self.timestamp)
if self.timestamp:
dt_object = datetime.fromtimestamp(self.timestamp)
timestr = dt_object.strftime("%-d %b %Y %H:%M")
log('timestr: '+timestr)
author_section_layout.add_widget(PostTimestampLabel(text=timestr))
# author_section_layout.add_widget(author_avatar)
# self.add_widget(author_section_layout)
@ -82,7 +104,7 @@ class PostCard(MDCard):
# post_layout.add_widget(content)
scroller = PostScrollView()
self.scroller = scroller = PostScrollView()
self.add_widget(author_section_layout)
# self.add_widget(MDLabel(text='hello'))
log('img_src ' + str(bool(self.img_src)))
@ -132,18 +154,14 @@ class FeedScreen(ProtectedScreen):
i=0
lim=25
for i,post in enumerate(reversed(self.app.get_posts())):
for i,post in enumerate(self.app.get_posts()):
log('third?')
#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',''))
post_obj = PostCard(post)
log(post)
self.posts.append(post_obj)
self.ids.post_carousel.add_widget(post_obj)

@ -3,73 +3,161 @@
#:import PostCard screens.feed.feed.PostCard
<AddPostScreen>:
name: 'post'
id: post_screen
<AddPostTextField>
id: post_content_input
hint_text: "word?"
required: False
# write_tab: False
multiline: True
helper_text_mode: "persistent"
helper_text: "word?"
color_mode: 'custom'
# size_hint_y:0.5
size_hint: (1,None)
size: ('300dp','300dp')
pos_hint: {'center_x': 0.5}
line_color_focus: 1,0,0,1
line_color_normal: 1,0,0,1
current_hint_text_color: 1,0,0,1
max_text_length: 10
# mode:'fill'
font_size:'23dp'
# font_style:'H5'
MyBoxLayout:
id: postbox
size_hint:0.5,0.2
# FileChoose:
# size_hint_y: 0.1
# on_release: self.choose()
# text: 'Select a file'
MDTextField:
id: post_content_input
hint_text: "word?"
required: False
# write_tab: False
multiline: True
helper_text_mode: "on_error"
color_mode: 'custom'
size_hint_y:0.5
# size: ('300dp','300dp')
line_color_focus: 1,0,0,1
line_color_normal: 0,0,0,1
current_hint_text_color: 1,0,0,1
max_text_length: 100
mode:'fill'
<ButtonLayout>:
id: buttonbox
# size_hint_y: None
adaptive_width: True
height: '56dp'
spacing: '10dp'
pos_hint: {'center_x': .5, 'y':0.05}
# md_bg_color: 1,1,0,1
<UploadButton>:
id: file_chooser_button
text: "upload"
#text: app.root.ids.scr_mngr.etc
on_release: self.screen.choose()
#app.register(username.text, password.text)
theme_text_color: "Custom"
text_color: 1,0,0,1
md_bg_color: 0,0,0,1
font_size: '28sp'
# fill:1,0,0,1
font_name: 'assets/overpass-mono-regular.otf'
<PostButton>:
text: "post"
on_release: self.screen.post() #self.post_content_input.text, file_chooser_button.selection)
theme_text_color: "Custom"
text_color: 1,0,0,1
md_bg_color: 0,0,0,1
font_size: '28sp'
# fill:1,0,0,1
font_name: 'assets/overpass-mono-regular.otf'
<PostStatus>:
id: post_status
text:"" #self.add_post_screen.post_id
size_hint:(None,None)
md_bg_color:0,0,0,1
pos_hint:{'center_x':.5, 'y':0.1}
text_color: 1,0,0,1
md_bg_color: 0,0,0,1
font_size: '25sp'
# fill:1,0,0,1
font_name: 'assets/overpass-mono-regular.otf'
<ProgressPopup>:
type: "custom"
size_hint: (None, None)
size: ('200dp','200dp')
md_bg_color: 0,0,0,1
MDBoxLayout:
id: buttonbox
# size_hint_y: None
adaptive_width: True
height: '56dp'
spacing: '10dp'
pos_hint: {'center_x': .5, 'y':0.41}
FileChoose:
id: file_chooser_button
text: "upload"
#text: app.root.ids.scr_mngr.etc
on_release: self.choose()
#app.register(username.text, password.text)
theme_text_color: "Custom"
text_color: 1,0,0,1
md_bg_color: 0,0,0,1
id: popup_box_layout
size_hint:(1,1)
orientation: 'vertical'
cols:1
md_bg_color: 0,0,0,1
spacing:'0dp'
padding:'0dp'
# radius:[20,]
# border_radius:20
canvas:
Color:
rgb: 1,0,0,1
Line:
width: 1
rectangle: (self.x, self.y, self.width, self.height)
# radius:[20,]
# border_radius:20
MDRectangleFlatButton:
text: "post"
on_release: app.post(post_content_input.text, file_chooser_button.selection)
#app.root.change_screen("welcome")
theme_text_color: "Custom"
MDLabel:
size_hint:(None,None)
id: progress_label
text: ''
halign: 'center'
theme_text_color: 'Custom'
text_color: 1,0,0,1
md_bg_color: 0,0,0,1
font_size: '18dp'
font_name: 'assets/overpass-mono-regular.otf'
pos_hint: {'center_x': .5, 'center_y': 0.5}
MDSpinner:
size_hint: None, None
size: '46dp','46dp'
pos_hint: {'center_x': .5, 'center_y': 0.5}
active: True
color:1,0,0,1
<MessagePopup>:
type: "custom"
size_hint: None,None
size: ('300dp','300dp')
md_bg_color: 0,0,0,1
MDBoxLayout:
id: msg_popup_box_layout
size_hint:(1,1)
orientation: 'vertical'
cols:1
md_bg_color: 0,0,0,1
spacing:'0dp'
padding:'0dp'
pos_hint: {'center_x':0.5, 'center_y':0.5}
# radius:[20,]
# border_radius:20
canvas:
Color:
rgb: 1,0,0,1
Line:
width: 1
rectangle: (self.x, self.y, self.width, self.height)
# radius:[20,]
# border_radius:20
MDLabel:
id: post_status
text:"" #self.add_post_screen.post_id
theme_text_color: 'Error'
pos_hint:{'center_x':.5}
# size_hint:(None,None)
id: msg_label
text: ''
halign: 'center'
# valign: 'middle'
theme_text_color: 'Custom'
text_color: 1,0,0,1
font_size: '18dp'
font_name: 'assets/overpass-mono-regular.otf'
pos_hint: {'center_x': .5, 'y': 0}
<AddPostScreen>:
name: 'post'
id: post_screen
<ViewPostScreen>:
name: 'view'

@ -1,14 +1,43 @@
from screens.base import ProtectedScreen
from plyer import filechooser
from kivymd.uix.button import MDRectangleFlatButton, MDIconButton
from kivymd.uix.label import MDLabel
from kivymd.uix.textfield import MDTextField
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.button import MDRectangleFlatButton, MDIconButton, MDRaisedButton
from kivy.properties import ListProperty,ObjectProperty
from kivy.app import App
from main import log
from screens.feed.feed import *
import os
import os,time,threading
from threading import Thread
class FileChoose(MDRectangleFlatButton):
from kivymd.uix.dialog import MDDialog
# # Progress bar code
# class ProgressPopup(MDDialog):
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
# content = MDLabel(font_style='Body1',
# theme_text_color='Secondary',
# text=kwargs.get('text',''),
# size_hint_y=None,
# valign='top')
# content.bind(texture_size=content.setter('size'))
# self.dialog = MDDialog(title="Close",
# content=content,
# size_hint=(.3, None),
# height='200dp')
# self.dialog.add_action_button("Close me!",
# action=lambda *x: self.dismiss_callback())
# self.dialog.open()
class ProgressPopup(MDDialog): pass
class MessagePopup(MDDialog): pass
class UploadButton(MDRectangleFlatButton):
'''
Button that triggers 'filechooser.open_file()' and processes
the data response from filechooser Activity.
@ -28,6 +57,8 @@ class FileChoose(MDRectangleFlatButton):
'''
self.selection = selection
def on_selection(self, *a, **k):
'''
Update TextInput.text after FileChoose.selection is changed
@ -36,10 +67,135 @@ class FileChoose(MDRectangleFlatButton):
pass
#App.get_running_app().root.ids.result.text = str(self.selection)
class AddPostTextField(MDTextField): pass
class ButtonLayout(MDBoxLayout): pass
class PostButton(MDRectangleFlatButton): pass
class PostStatus(MDRectangleFlatButton): pass
class AddPostScreen(ProtectedScreen):
post_id = ObjectProperty()
pass
def on_pre_enter(self):
# clear
if hasattr(self,'post_status'): self.remove_widget(self.post_status)
if hasattr(self,'post_textfield'): self.post_textfield.text=''
post_json = {'author':self.app.username, 'timestamp':time.time()}
self.post_card = post = PostCard(post_json)
self.post_textfield = post_TextField = AddPostTextField()
post_TextField.line_color_focus=(1,0,0,1)
post_TextField.line_color_normal=(1,0,0,1)
post_TextField.current_hint_text_color=(1,0,0,1)
post_TextField.font_name='assets/overpass-mono-regular.otf'
post_TextField.hint_text='word?'
post.remove_widget(post.scroller)
post.add_widget(post_TextField)
self.add_widget(post)
self.button_layout = ButtonLayout()
self.upload_button = UploadButton()
self.upload_button.screen = self
self.post_button = PostButton()
self.post_button.screen = self
self.post_status = PostStatus()
self.post_status_added = False
self.button_layout.add_widget(self.upload_button)
self.button_layout.add_widget(self.post_button)
self.post_button.md_bg_color=(0,0,0,1)
self.upload_button.md_bg_color=(0,0,0,1)
self.post_status.md_bg_color=(0,0,0,1)
self.add_widget(self.button_layout)
# self.add_widget(self.post_status)
def write_post_status(self,x):
self.post_status.text=str(x)
if not self.post_status_added:
self.add_widget(self.post_status)
self.post_status_added=True
def open_dialog(self,msg):
if not hasattr(self,'dialog') or not self.dialog:
self.dialog = ProgressPopup()
log(self.dialog.ids.keys())
self.dialog.ids.progress_label.text=msg
self.dialog.open()
def open_msg_dialog(self,msg):
if not hasattr(self,'msg_dialog') or not self.msg_dialog:
self.msg_dialog = MessagePopup()
self.msg_dialog.ids.msg_label.text=msg
self.msg_dialog.open()
def close_dialog(self):
if hasattr(self,'dialog'):
self.dialog.dismiss()
def close_msg_dialog(self):
if hasattr(self,'msg_dialog'):
self.msg_dialog.dismiss()
def choose(self):
# time.sleep(5)
self.upload_button.choose()
self.orig_img_src = self.upload_button.selection
self.open_dialog('uploading')
# self.upload()
# self.close_dialog()
mythread = threading.Thread(target=self.upload)
mythread.start()
def upload(self):
rdata = self.app.upload(self.orig_img_src)
for k,v in rdata.items():
log('data!!!' + str(k) +':'+str(v))
setattr(self,k,v)
self.add_image()
self.close_dialog()
def add_image(self):
if hasattr(self,'image'):
self.image.source=self.cache_filename
else:
self.image_layout = image_layout = PostImageLayout()
self.image = image = PostImage(source=self.cache_filename)
image.height = '300dp'
image_layout.add_widget(image)
image_layout.height='300dp'
self.post_card.add_widget(image_layout,index=1)
def post(self):
# check?
content = self.post_textfield.text
lencontent = len(content)
maxlen = int(self.post_textfield.max_text_length)
lendiff = lencontent - maxlen
if lendiff>0:
self.open_msg_dialog(f'Text is currently {lencontent} characters long, which is {lendiff} over the maximum text length of {maxlen} characters.\n\n({lencontent}/{maxlen})')
return
# log('?????????????????'+self.media_uid)
if not hasattr(self,'media_uid') and self.upload_button.selection:
log('REUPLOADING')
self.upload()
def do_post():
media_uid = self.media_uid if hasattr(self,'media_uid') else None
self.app.post(content=content, media_uid=media_uid) #, logger=logger)
self.close_dialog()
self.open_dialog('posting')
Thread(target=do_post).start()
class ViewPostScreen(ProtectedScreen):
post_id = ObjectProperty()
@ -50,23 +206,9 @@ class ViewPostScreen(ProtectedScreen):
self.remove_widget(child)
post_json = self.app.get_post(self.root.post_id)
log(post_json)
img_src = post_json.get('img_src','')
content = post_json.get('content','')
cache_img_src = os.path.join('cache','img',img_src) if img_src else ''
kwargs = dict(author='Marx Zuckerberg',
title='',
img_src=img_src,
content=content)
log(kwargs)
post = PostCard(**kwargs)
print(post)
post = PostCard(post_json)
self.add_widget(post)
def on_enter(self):
for child in self.children: child.load_image()

@ -59,9 +59,10 @@ class Post(StructuredNode):
# properties
uid = UniqueIdProperty()
content = StringProperty()
has_media = RelationshipTo('Media','HAS_MEDIA')
timestamp = FloatProperty(index=True)
# relations
has_media = RelationshipTo('Media','HAS_MEDIA')
written_by = RelationshipFrom('Person','WROTE')
located_in = RelationshipTo('Place','LOCATED')
@ -75,7 +76,7 @@ class Post(StructuredNode):
@property
def img_src(self):
print(dir(self.has_media))
# print(dir(self.has_media))
if self.has_media:
media = self.has_media[0]
return media.filename
@ -83,7 +84,7 @@ class Post(StructuredNode):
@property
def data(self):
return {'uid':self.uid, 'content':self.content, 'img_src':self.img_src}
return {'uid':self.uid, 'content':self.content, 'img_src':self.img_src, 'timestamp':self.timestamp, 'author':self.author.name}
class Place(StructuredNode):

@ -33,8 +33,6 @@ def home(): return {'error':'404 go home friend'}
def login():
data=request.json
print('sleeping...')
gevent.sleep(10)
name=data.get('name','')
passkey=data.get('passkey','')
@ -136,7 +134,7 @@ def post(post_id=None):
print('POST /api/post:',data)
# make post
post = Post(content=data.get('content','')).save()
post = Post(content=data.get('content',''), timestamp=data.get('timestamp')).save()
# attach author
name = data.get('username')
@ -191,7 +189,7 @@ def get_posts(name=None):
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()]
data = [p.data for p in Post.nodes.order_by('-timestamp')]
# print(data)
return jsonify({'posts':data})

Loading…
Cancel
Save