frontend login work

macdev
quadrismegistus 4 years ago
parent aefca13fe9
commit 62845661f8

@ -0,0 +1,96 @@
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.uix.screenmanager import Screen
from kivymd.icon_definitions import md_icons
from kivymd.app import MDApp
from kivymd.uix.list import OneLineIconListItem
Builder.load_string(
'''
#:import images_path kivymd.images_path
<CustomOneLineIconListItem>:
IconLeftWidget:
icon: root.icon
<PreviousMDIcons>:
BoxLayout:
orientation: 'vertical'
spacing: dp(10)
padding: dp(20)
BoxLayout:
size_hint_y: None
height: self.minimum_height
MDIconButton:
icon: 'magnify'
MDTextField:
id: search_field
hint_text: 'Search icon'
on_text: root.set_list_md_icons(self.text, True)
RecycleView:
id: rv
key_viewclass: 'viewclass'
key_size: 'height'
RecycleBoxLayout:
padding: dp(10)
default_size: None, dp(48)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
'''
)
class CustomOneLineIconListItem(OneLineIconListItem):
icon = StringProperty()
class PreviousMDIcons(Screen):
def set_list_md_icons(self, text="", search=False):
'''Builds a list of icons for the screen MDIcons.'''
def add_icon_item(name_icon):
self.ids.rv.data.append(
{
"viewclass": "CustomOneLineIconListItem",
"icon": name_icon,
"text": name_icon,
"callback": lambda x: x,
}
)
self.ids.rv.data = []
for name_icon in md_icons.keys():
if search:
if text in name_icon:
add_icon_item(name_icon)
else:
add_icon_item(name_icon)
class MainApp(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = PreviousMDIcons()
def build(self):
return self.screen
def on_start(self):
self.screen.set_list_md_icons()
MainApp().run()

@ -2,8 +2,12 @@
# change this to your external ip address for your server # change this to your external ip address for your server
#(needs to be external to allow tor routing) #(needs to be external to allow tor routing)
DEFAULT_SCREEN='feed' DEFAULT_SCREEN='feed'
HORIZONTAL = False
WINDOW_SIZE = (1136,640) if HORIZONTAL else (640,1136) import random
HORIZONTAL = random.choice([True,True,True,False])
FACTOR=1
WINDOW_SIZE = (1136*FACTOR,640*FACTOR) if HORIZONTAL else (640*FACTOR,1136*FACTOR)
# monkeypatching the things that asyncio needs # monkeypatching the things that asyncio needs
import subprocess import subprocess
@ -257,35 +261,39 @@ class MainApp(MDApp):
def login(self,un=None,pw=None): def login(self,un=None,pw=None):
dat = self.api.login(un,pw) async def do():
self.log(dat) dat = await self.api.login(un,pw)
if 'success' in dat: self.log(dat)
self.save_login(un) if 'success' in dat:
elif 'error' in dat: self.save_login(un)
self.root.ids.login_screen.login_status.text=dat['error'] elif 'error' in dat:
return False self.root.ids.login_screen.login_status.text=dat['error']
def register(self,un,pw):
dat = self.api.register(un,pw)
if 'success' in dat:
self.save_login(un)
return True
elif 'error' in dat:
self.root.ids.login_screen.login_status.text=dat['error']
return False return False
asyncio.create_task(do())
def upload(self,filename,file_id=None): def register(self,un,pw):
async def do():
dat = await self.api.register(un,pw)
if 'success' in dat:
self.save_login(un)
return True
elif 'error' in dat:
self.root.ids.login_screen.login_status.text=dat['error']
return False
asyncio.create_task(do())
async def upload(self,filename,file_id=None):
self.log('uploading filename:',filename) self.log('uploading filename:',filename)
rdata=self.api.upload(filename,file_id=file_id) rdata=await self.api.upload(filename,file_id=file_id)
self.log('upload result:',rdata) self.log('upload result:',rdata)
if rdata is not None: if rdata is not None:
rdata['success']='File uploaded' rdata['success']='File uploaded'
return rdata return rdata
return {'error':'Upload failed'} return {'error':'Upload failed'}
def download(self,file_id,output_fn=None): async def download(self,file_id,output_fn=None):
self.log('downloading:',file_id) self.log('downloading:',file_id)
file_dat = self.api.download(file_id) file_dat = await self.api.download(file_id)
if not output_fn: if not output_fn:
file_id=file_dat['id'] file_id=file_dat['id']
file_ext=file_dat['ext'] file_ext=file_dat['ext']
@ -325,26 +333,12 @@ class MainApp(MDApp):
async def get_posts(self): async def get_posts(self):
return await self.api.get_posts() return await self.api.get_posts()
def get_my_posts(self): async def get_my_posts(self):
return self.api.get_posts('/author/'+self.username) return await self.api.get_posts('/author/'+self.username)
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)
self.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
### SYNCHRONOUS?
def app_func(self): def app_func(self):
'''This will run both methods asynchronously and then block until they '''This will run both methods asynchronously and then block until they
are finished are finished
@ -361,31 +355,6 @@ class MainApp(MDApp):
return asyncio.gather(run_wrapper(), self.other_task) return asyncio.gather(run_wrapper(), self.other_task)
async def waste_time_freely(self):
'''This method is also run by the asyncio loop and periodically prints
something.
'''
try:
i = 0
while True:
if self.root is not None:
#status = self.root.ids.label.status
status='TimeWaster'
self.log('{} on the beach'.format(status))
# # get some sleep
# if self.root.ids.btn1.state != 'down' and i >= 2:
# i = 0
# self.log('Yawn, getting tired. Going to sleep')
# self.root.ids.btn1.trigger_action()
i += 1
await asyncio.sleep(2)
except asyncio.CancelledError as e:
self.log('Wasting time was canceled', e)
finally:
# when canceled, print that it finished
self.log('Done wasting time')
if __name__ == '__main__': if __name__ == '__main__':

@ -74,7 +74,7 @@ MyLayout:
background_palette: 'Red' background_palette: 'Red'
background_hue: '500' background_hue: '500'
specific_text_color: 1,0,0,1 specific_text_color: 1,0,0,1
right_action_items: [['post-outline', partial(root.change_screen, 'feed')], ['pencil-plus-outline', partial(root.change_screen, 'post')], ['message-processing-outline', partial(root.change_screen, 'messages')], ['bell-outline', partial(root.change_screen, 'notifications')], ['account-circle-outline', partial(root.change_screen, 'profile')]] right_action_items: [['card-text-outline', partial(root.change_screen, 'feed')], ['pencil-plus-outline', partial(root.change_screen, 'post')], ['message-outline', partial(root.change_screen, 'messages')], ['bell-outline', partial(root.change_screen, 'notifications')], ['account-circle-outline', partial(root.change_screen, 'profile')]]
#left_action_items: [[f"assets/fist2.png", partial(root.change_screen, 'feed')]] #left_action_items: [[f"assets/fist2.png", partial(root.change_screen, 'feed')]]
font_context: None font_context: None
font_name: f'assets/Strengthen.ttf' font_name: f'assets/Strengthen.ttf'

@ -159,7 +159,7 @@
border_radius:20 border_radius:20
canvas: canvas:
Color: Color:
rgba: 1,0,0,0.5 rgba: 0,0,0,0.5
Line: Line:
width: 1 width: 1
rounded_rectangle: (self.x, self.y, self.width, self.height, 20, 20, 20, 20) rounded_rectangle: (self.x, self.y, self.width, self.height, 20, 20, 20, 20)

@ -172,6 +172,8 @@ class FeedScreen(ProtectedScreen):
posts = ListProperty() posts = ListProperty()
def on_pre_enter(self): def on_pre_enter(self):
super().on_pre_enter()
async def go(): async def go():
# self.log('ids:' +str(self.ids.post_carousel.ids)) # self.log('ids:' +str(self.ids.post_carousel.ids))
for post in self.posts: for post in self.posts:

@ -12,16 +12,40 @@
id: loginbox id: loginbox
orientation:'vertical' orientation:'vertical'
cols:1 cols:1
size_hint:0.5,0.2 size_hint:0.5,None
pos_hint: {'center_x':0.5,'center_y':0.5} pos_hint: {'center_x':0.5,'center_y':0.5}
md_bg_color: 0,0,0,1 md_bg_color: 0,0,0,1
radius:[20,] radius:[20,]
border_radius:20 border_radius:20
spacing:'10dp' spacing:'10dp'
padding:'10dp' padding:'25dp'
adaptive_height: True
<UsernameLayout>:
cols:2
orientation:'horizontal'
adaptive_height: True
size_hint:1,None
# pos_hint:{'right':0.9}
# spacing:'100sp'
# md_bg_color:1,1,0,1
<UsernameLabel>:
theme_text_color: 'Custom'
text_color: 1,0,0,1
# width:'100sp'
adaptive_width: True
size_hint:None,None
# md_bg_color:1,0,0,1
# pos_hint: {'y':1}
halign:'center'
<UsernameField>: <UsernameField>:
id: username id: username
text: ""
hint_text: "username" hint_text: "username"
required: True required: True
write_tab: False write_tab: False
@ -32,13 +56,14 @@
line_color_normal: 1,0,0,1 line_color_normal: 1,0,0,1
current_hint_text_color: 1,0,0,1 current_hint_text_color: 1,0,0,1
error_color:1,0,0,1 error_color:1,0,0,1
# pos_hint: {'x':1,'y':0.8} pos_hint: {'center_x':0.5,'y':0.2}
size_hint:0.8,None
# size_hint:(None,None)
<PasswordField>: <PasswordField>:
id: password id: password
text: ""
password: True password: True
hint_text: "password" hint_text: "password"
required: True required: True
@ -50,16 +75,21 @@
line_color_normal: 1,0,0,1 line_color_normal: 1,0,0,1
current_hint_text_color: 1,0,0,1 current_hint_text_color: 1,0,0,1
text_color: 1,0,0,1 text_color: 1,0,0,1
# pos_hint: {'center_x':1,'y':0.8} pos_hint: {'center_x':0.5,'y':0.2}
# size_hint:(None,None) size_hint:0.8,None
<LoginButtonLayout>: <LoginButtonLayout>:
id: buttonbox id: buttonbox
size_hint_y: None orientation:'horizontal'
cols: 2
# size_hint_y: None
adaptive_width: True adaptive_width: True
height: '56dp' height: '56dp'
spacing: '10dp' spacing: '25dp'
pos_hint: {'center_x': .5} padding: '10dp'
# md_bg_color:1,1,0,1
size_hint:None,None
pos_hint: {'center_x': .5}#, 'bottom':1}
<LoginButton>: <LoginButton>:
text: "login" text: "login"
@ -69,6 +99,8 @@
theme_text_color: "Custom" theme_text_color: "Custom"
text_color: 1,0,0,1 text_color: 1,0,0,1
md_bg_color: 0,0,0,1 md_bg_color: 0,0,0,1
size_hint:None,None
# pos_hint: {'center_x': .5, 'bottom':1}
<RegisterButton>: <RegisterButton>:
text: "register" text: "register"
@ -77,12 +109,16 @@
theme_text_color: "Custom" theme_text_color: "Custom"
text_color: 1,0,0,1 text_color: 1,0,0,1
md_bg_color: 0,0,0,1 md_bg_color: 0,0,0,1
# size_hint:1,None
<LoginStatus>: <LoginStatus>:
id: login_status id: login_status
text:"" text:""
theme_text_color: 'Error' theme_text_color: 'Error'
pos_hint:{'center_x':.5} size_hint:1,1
halign:'center'
pos_hint:{'center_x':.5, 'center_y':0.5}
<LoginScreen>: <LoginScreen>:

@ -3,6 +3,7 @@ from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.textfield import MDTextField from kivymd.uix.textfield import MDTextField
from kivymd.uix.button import MDRectangleFlatButton from kivymd.uix.button import MDRectangleFlatButton
from kivymd.uix.label import MDLabel from kivymd.uix.label import MDLabel
from main import MyLabel
class LoginBoxLayout(MDBoxLayout): pass class LoginBoxLayout(MDBoxLayout): pass
class LoginButtonLayout(MDBoxLayout): pass class LoginButtonLayout(MDBoxLayout): pass
@ -12,6 +13,9 @@ class LoginButton(MDRectangleFlatButton): pass
class RegisterButton(MDRectangleFlatButton): pass class RegisterButton(MDRectangleFlatButton): pass
class LoginStatus(MDLabel): pass class LoginStatus(MDLabel): pass
class UsernameLayout(MDBoxLayout): pass
class UsernameLabel(MDLabel): pass
class LoginScreen(BaseScreen): class LoginScreen(BaseScreen):
#def on_pre_enter(self): #def on_pre_enter(self):
# global app # global app
@ -22,27 +26,51 @@ class LoginScreen(BaseScreen):
#log('hello?') #log('hello?')
self.layout = LoginBoxLayout() self.layout = LoginBoxLayout()
self.layout_username = UsernameLayout()
self.label_username = UsernameLabel(text="username:")
self.username_field = UsernameField() self.username_field = UsernameField()
self.username_field.line_color_focus=(1,0,0,1) self.username_field.line_color_focus=(1,0,0,1)
self.layout.add_widget(self.username_field) self.username_field.line_color_normal=(1,0,0,0.25)
self.username_field.font_name='assets/font.otf'
self.layout_username.add_widget(self.label_username)
self.layout_username.add_widget(self.username_field)
self.layout.add_widget(self.layout_username)
#log(self.username_field) #log(self.username_field)
# self.username_field.text='hello????' # self.username_field.text='hello????'
self.layout_password = UsernameLayout()
self.label_password = UsernameLabel(text='password:')
self.label_password.font_name='assets/font.otf'
self.label_username.font_name='assets/font.otf'
self.password_field = PasswordField() self.password_field = PasswordField()
self.password_field.line_color_focus=(1,0,0,1) self.password_field.line_color_focus=(1,0,0,1)
self.layout.add_widget(self.password_field) self.password_field.line_color_normal=(1,0,0,0.25)
self.password_field.font_name='assets/font.otf'
self.layout_password.add_widget(self.label_password)
self.layout_password.add_widget(self.password_field)
self.layout.add_widget(self.layout_password)
self.layout_buttons = LoginButtonLayout() self.layout_buttons = LoginButtonLayout()
self.layout.add_widget(self.layout_buttons) self.layout.add_widget(self.layout_buttons)
self.login_button = LoginButton() self.login_button = LoginButton()
self.login_button.font_name='assets/font.otf'
self.layout_buttons.add_widget(self.login_button) self.layout_buttons.add_widget(self.login_button)
self.register_button = RegisterButton() self.register_button = RegisterButton()
self.register_button.font_name='assets/font.otf'
# self.register_button = # self.register_button =
self.layout_buttons.add_widget(self.register_button) self.layout_buttons.add_widget(self.register_button)
self.login_status = LoginStatus() self.login_status = LoginStatus()
self.login_status.font_name='assets/font.otf'
self.layout.add_widget(self.login_status) self.layout.add_widget(self.login_status)

@ -56,6 +56,8 @@ class PostScreen(ProtectedScreen):
post_id = ObjectProperty() post_id = ObjectProperty()
def on_pre_enter(self): def on_pre_enter(self):
super().on_pre_enter()
# clear # clear
if hasattr(self,'post_status'): self.remove_widget(self.post_status) if hasattr(self,'post_status'): self.remove_widget(self.post_status)
if hasattr(self,'post_textfield'): self.post_textfield.text='' if hasattr(self,'post_textfield'): self.post_textfield.text=''

@ -13,7 +13,7 @@ def run_command():
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
class Watcher: class Watcher:
DIRECTORY_TO_WATCH = os.path.join(os.path.expanduser('~'),"/github/Komrade/p2p") DIRECTORY_TO_WATCH = os.path.join(os.path.expanduser('~'),"/github/Komrade/")
def __init__(self): def __init__(self):
self.observer = Observer() self.observer = Observer()

@ -82,7 +82,7 @@ class Api(object):
i = 0 i = 0
self._node = await self.connect() self._node = await self.connect()
while True: while True:
self.log(f'Node status (pulse {i}): {self._node}') self.log(f'Node status (minute {i}): {self._node}')
# # get some sleep # # get some sleep
# if self.root.ids.btn1.state != 'down' and i >= 2: # if self.root.ids.btn1.state != 'down' and i >= 2:
@ -90,8 +90,9 @@ class Api(object):
# self.log('Yawn, getting tired. Going to sleep') # self.log('Yawn, getting tired. Going to sleep')
# self.root.ids.btn1.trigger_action() # self.root.ids.btn1.trigger_action()
i += 1 #i += 1
await asyncio.sleep(10) await asyncio.sleep(60)
# pass
except asyncio.CancelledError as e: except asyncio.CancelledError as e:
self.log('Wasting time was canceled', e) self.log('Wasting time was canceled', e)
finally: finally:
@ -169,33 +170,29 @@ class Api(object):
# self.log('OH NO!',sys.getsizeof(value_json)) # self.log('OH NO!',sys.getsizeof(value_json))
return await self.set(key,value_json) return await self.set(key,value_json)
def has(self,key): async def has(self,key):
return self.get(key) is not None val=await self.get(key)
return val is not None
## PERSONS ## PERSONS
def get_person(self,username): async def get_person(self,username):
return self.get_json('/person/'+username) return await self.get_json('/person/'+username)
def set_person(self,username,public_key): async def set_person(self,username,public_key):
pem_public_key = save_public_key(public_key,return_instead=True) pem_public_key = save_public_key(public_key,return_instead=True)
obj = {'name':username, 'public_key':pem_public_key.decode()} obj = {'name':username, 'public_key':pem_public_key.decode()}
self.set_json('/person/'+username,obj) await self.set_json('/person/'+username,obj)
## Register ## Register
def register(self,name,passkey): async def register(self,name,passkey):
if not (name and passkey): return {'error':'Name and password needed'}
if not (name and passkey): person = await self.get_person(name)
error('name and passkey not set') if person is not None: return {'error':'Username already exists'}
return {'error':'Register failed'}
person = self.get_person(name)
if person is not None:
self.log('error! person exists')
return {'error':'Register failed'}
private_key,public_key = new_keys(password=passkey,save=False) private_key,public_key = new_keys(password=passkey,save=False)
pem_private_key = save_private_key(private_key,password=passkey,return_instead=True) pem_private_key = save_private_key(private_key,password=passkey,return_instead=True)
@ -204,36 +201,38 @@ class Api(object):
self.app_storage.put('_keys', self.app_storage.put('_keys',
private=str(pem_private_key.decode()), private=str(pem_private_key.decode()),
public=str(pem_public_key.decode())) #(private_key,password=passkey) public=str(pem_public_key.decode())) #(private_key,password=passkey)
self.set_person(name,public_key) await self.set_person(name,public_key)
self.log('success! Account created')
return {'success':'Account created', 'username':name} return {'success':'Account created', 'username':name}
def load_private_key(self,password): def load_private_key(self,password):
if not self.app_storage.exists('_keys'): return None if not self.app_storage.exists('_keys'): return None
pem_private_key=self.app_storage.get('_keys').get('private') pem_private_key=self.app_storage.get('_keys').get('private')
try: try:
return load_private_key(pem_private_key.encode(),password) return {'success':load_private_key(pem_private_key.encode(),password)}
except ValueError as e: except ValueError as e:
self.log('!!',e) self.log('!!',e)
return None return {'error':'Incorrect password'}
## LOGIN ## LOGIN
def login(self,name,passkey): async def login(self,name,passkey):
# verify input # verify input
if not (name and passkey): if not (name and passkey):
return {'error':'Name and password required'} return {'error':'Name and password required'}
# try to load private key # try to load private key
private_key = self.load_private_key(passkey) private_key_dat = self.load_private_key(passkey)
if private_key is None: if 'error' in private_key_dat:
return {'error':'You have never registered on this device'} return {'error':private_key_dat['error']}
if not 'success' in private_key_dat:
return {'error':'Incorrect password?'}
private_key = private_key_dat['success']
# see if user exists # see if user exists
person = self.get_person(name) person = await self.get_person(name)
self.log(person) self.log(person)
if person is None: if person is None:
return {'error':'Login failed'} return {'error':'Login failed'}
@ -247,7 +246,7 @@ class Api(object):
#log('REAL PUBLIC',real_public_key.public_numbers()) #log('REAL PUBLIC',real_public_key.public_numbers())
if public_key.public_numbers() != real_public_key.public_numbers(): if public_key.public_numbers() != real_public_key.public_numbers():
return {'error':'keys do not match!'} return {'error':'Keys do not match!'}
return {'success':'Login successful', 'username':name} return {'success':'Login successful', 'username':name}
async def append_json(self,key,data): async def append_json(self,key,data):
@ -258,7 +257,7 @@ class Api(object):
return {'success':'Length increased to %s' % len(new)} return {'success':'Length increased to %s' % len(new)}
return {'error':'Could not append json'} return {'error':'Could not append json'}
def upload(self,filename,file_id=None, uri='/file/',uri_part='/part/'): async def upload(self,filename,file_id=None, uri='/file/',uri_part='/part/'):
import sys import sys
if not file_id: file_id = get_random_id() if not file_id: file_id = get_random_id()
@ -280,7 +279,7 @@ class Api(object):
if len(parts)>=buffer_size: if len(parts)>=buffer_size:
self.log('setting...') self.log('setting...')
self.set(part_keys,parts) await self.set(part_keys,parts)
part_keys=[] part_keys=[]
PARTS+=parts PARTS+=parts
parts=[] parts=[]
@ -288,26 +287,26 @@ class Api(object):
# set all parts # set all parts
#self.set(part_keys,PARTS) #self.set(part_keys,PARTS)
self.log('# parts:',len(PARTS)) self.log('# parts:',len(PARTS))
if parts and part_keys: self.set(part_keys, parts) if parts and part_keys: await self.set(part_keys, parts)
# how many parts? # how many parts?
self.log('# pieces!',len(part_ids)) self.log('# pieces!',len(part_ids))
file_store = {'ext':os.path.splitext(filename)[-1][1:], 'parts':part_ids} file_store = {'ext':os.path.splitext(filename)[-1][1:], 'parts':part_ids}
self.log('FILE STORE??',file_store) self.log('FILE STORE??',file_store)
self.set_json(uri+file_id,file_store) await self.set_json(uri+file_id,file_store)
# file_store['data'].seek(0) # file_store['data'].seek(0)
file_store['id']=file_id file_store['id']=file_id
return file_store return file_store
def download(self,file_id): async def download(self,file_id):
file_store = self.get_json('/file/'+file_id) file_store = await self.get_json('/file/'+file_id)
if file_store is None: return if file_store is None: return
self.log('file_store!?',file_store) self.log('file_store!?',file_store)
keys = ['/part/'+x for x in file_store['parts']] keys = ['/part/'+x for x in file_store['parts']]
pieces = self.get(keys) pieces = await self.get(keys)
file_store['parts_data']=pieces file_store['parts_data']=pieces
return file_store return file_store
@ -342,160 +341,25 @@ class Api(object):
## CREATE ## func
def bytes_from_file(filename,chunksize=8192):
with open(filename, 'rb') as f:
while True:
piece = f.read(chunksize)
if not piece:
break
yield piece
def get_random_id(): def get_random_id():
import uuid import uuid
return uuid.uuid4().hex return uuid.uuid4().hex
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])
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
def download(prefix, filename):
filedir = os.path.join(app.config['UPLOAD_DIR'], prefix)
print(filedir, filename)
return send_from_directory(filedir, filename)
### READ
def get_followers(name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.followers]
return jsonify(data)
def get_follows(name=None):
person = Person.match(G, name).first()
data = [p.data for p in person.follows]
return jsonify(data)
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})
def get_post(id=None):
post = Post.match(G, int(id)).first()
data = post.data
return jsonify(data)
import sys
# def bytes_from_file(filename, chunksize=8192//2):
# with open(filename, "rb") as f:
# while True:
# chunk = f.read(chunksize)
# if chunk:
# self.log(type(chunk), sys.getsizeof(chunk))
# yield chunk
# #yield from chunk
# else:
# break
# def bytes_from_file(filename,chunksize=8192):
# with open(filename,'rb') as f:
# barray = bytearray(f.read())
# for part in barray[0:-1:chunksize]:
# self.log('!?',part)
# yield bytes(part)
def bytes_from_file(filename,chunksize=8192):
with open(filename, 'rb') as f:
while True:
piece = f.read(chunksize)
if not piece:
break
yield piece
# import sys
# def bytes_from_file(path,chunksize=8000):
# ''' Given a path, return an iterator over the file
# that lazily loads the file.
# '''
# path = Path(path)
# bufsize = get_buffer_size(path)
# with path.open('rb') as file:
# reader = partial(file.read1, bufsize)
# for chunk in iter(reader, bytes()):
# _bytes=bytearray()
# for byte in chunk:
# #if _bytes is None:
# # _bytes=byte
# #else:
# _bytes.append(byte)
# if sys.getsizeof(_bytes)>=8192:
# yield bytes(_bytes) #.bytes()
# _bytes=bytearray()
# if _bytes:
# yield bytes(_bytes)
# def get_buffer_size(path):
# """ Determine optimal buffer size for reading files. """
# st = os.stat(path)
# try:
# bufsize = st.st_blksize # Available on some Unix systems (like Linux)
# except AttributeError:
# bufsize = io.DEFAULT_BUFFER_SIZE
# return bufsize
def test_api(): def test_api():
api = Api() api = Api()

Binary file not shown.
Loading…
Cancel
Save