got posting/uploading working with p2p...
parent
d85063da16
commit
37774b95a9
@ -1,102 +0,0 @@
|
|||||||
#:import get_color_from_hex kivy.utils.get_color_from_hex
|
|
||||||
#:import images_path kivymd.images_path
|
|
||||||
#:import colors kivymd.color_definitions.colors
|
|
||||||
#:import partial functools.partial
|
|
||||||
#:import NoTransition kivy.uix.screenmanager.NoTransition
|
|
||||||
|
|
||||||
|
|
||||||
MyLayout:
|
|
||||||
scr_mngr: scr_mngr
|
|
||||||
orientation: 'vertical'
|
|
||||||
height: self.minimum_height
|
|
||||||
|
|
||||||
canvas:
|
|
||||||
Color:
|
|
||||||
rgba: 0,0,0,1 #get_color_from_hex(colors['Gray']['900'])
|
|
||||||
Rectangle:
|
|
||||||
pos: self.pos
|
|
||||||
size: self.size
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MyToolbar:
|
|
||||||
id: toolbar
|
|
||||||
title: app.title
|
|
||||||
pos_hint: {'center_x': .5, 'center_y': 1}
|
|
||||||
md_bg_color: 0,0,0,1
|
|
||||||
background_palette: 'Red'
|
|
||||||
background_hue: '500'
|
|
||||||
specific_text_color: 1,0,0,1
|
|
||||||
right_action_items: [['radio-tower', partial(root.change_screen, 'feed')], ['account-group', partial(root.change_screen, 'people')], ['calendar', partial(root.change_screen, 'events')], ['message-processing-outline', partial(root.change_screen, 'messages')], ['bell-outline', partial(root.change_screen, 'notifications')]]
|
|
||||||
left_action_items: [[f"spiral3.png", partial(root.change_screen, 'welcome')]]
|
|
||||||
|
|
||||||
ScreenManager:
|
|
||||||
id: scr_mngr
|
|
||||||
transition: NoTransition()
|
|
||||||
|
|
||||||
|
|
||||||
WelcomeScreen:
|
|
||||||
name: 'welcome'
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
text: "Turning and turning in the widening gyre \nThe falcon cannot hear the falconer;\nThings fall apart; the centre cannot hold;\nMere anarchy is loosed upon the world,\nThe blood-dimmed tide is loosed, and everywhere \nThe ceremony of innocence is drowned;\nThe best lack all conviction, while the worst \nAre full of passionate intensity.\n\nSurely some revelation is at hand;\nSurely the Second Coming is at hand. \nThe Second Coming! Hardly are those words out \nWhen a vast image out of Spiritus Mundi\nTroubles my sight: somewhere in sands of the desert \nA shape with lion body and the head of a man, \nA gaze blank and pitiless as the sun, \nIs moving its slow thighs, while all about it \nReel shadows of the indignant desert birds. \nThe darkness drops again; but now I know \nThat twenty centuries of stony sleep\nWere vexed to nightmare by a rocking cradle, \nAnd what rough beast, its hour come round at last, \nSlouches towards Bethlehem to be born?"
|
|
||||||
pos_hint: {"center_x": 0.5, "center_y": 0.5}
|
|
||||||
halign:"center"
|
|
||||||
theme_text_color: "Custom"
|
|
||||||
text_color: 1, 0, 0, 1
|
|
||||||
|
|
||||||
|
|
||||||
FeedScreen:
|
|
||||||
name: 'feed'
|
|
||||||
MDLabel:
|
|
||||||
text: "FEED Turning and turning in the widening gyre..."
|
|
||||||
pos_hint: {"center_x": 0.5, "center_y": 0.95}
|
|
||||||
halign:"center"
|
|
||||||
theme_text_color: "Custom"
|
|
||||||
text_color: 1, 0, 0, 1
|
|
||||||
|
|
||||||
PeopleScreen:
|
|
||||||
name: 'people'
|
|
||||||
MDLabel:
|
|
||||||
text: "The falcon cannot hear the falconer..."
|
|
||||||
pos_hint: {"center_x": 0.5, "center_y": 0.95}
|
|
||||||
halign:"center"
|
|
||||||
|
|
||||||
EventsScreen:
|
|
||||||
name: 'events'
|
|
||||||
|
|
||||||
MessagesScreen:
|
|
||||||
name: 'messages'
|
|
||||||
|
|
||||||
NotificationsScreen:
|
|
||||||
name: 'notifications'
|
|
||||||
|
|
||||||
# ScreenManager:
|
|
||||||
# BaseScreen:
|
|
||||||
# FeedScreen:
|
|
||||||
|
|
||||||
|
|
||||||
# <BaseScreen>:
|
|
||||||
# name: 'base'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# MDFillRoundFlatButton:
|
|
||||||
# text: "Gyre"
|
|
||||||
# halign: "center"
|
|
||||||
# pos_hint: {"center_x": 0.5, "center_y": 0.5}
|
|
||||||
# md_bg_color: get_color_from_hex(colors['Red']['500'])
|
|
||||||
|
|
||||||
|
|
||||||
# MDLabel:
|
|
||||||
# text: "Turning and turning in the widening gyre..."
|
|
||||||
# pos_hint: {"center_x": 0.5, "center_y": 0.435}
|
|
||||||
# halign:"center"
|
|
||||||
|
|
||||||
|
|
||||||
# <FeedScreen>
|
|
||||||
# name: 'feed'
|
|
||||||
# MDLabel:
|
|
||||||
# text: "The falcon cannot hear the falconer..."
|
|
||||||
# pos_hint: {"center_x": 0.5, "center_y": 0.3}
|
|
||||||
# halign:"center"
|
|
@ -1,58 +0,0 @@
|
|||||||
from kivy.uix.screenmanager import Screen,ScreenManager
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.button import MDFillRoundFlatButton
|
|
||||||
from kivy.lang import Builder
|
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
|
||||||
from kivymd.theming import ThemeManager
|
|
||||||
from kivy.properties import ObjectProperty
|
|
||||||
from kivymd.uix.label import MDLabel
|
|
||||||
|
|
||||||
class MyLayout(BoxLayout):
|
|
||||||
scr_mngr = ObjectProperty(None)
|
|
||||||
|
|
||||||
def change_screen(self, screen, *args):
|
|
||||||
self.scr_mngr.current = screen
|
|
||||||
|
|
||||||
class FeedScreen(Screen):
|
|
||||||
def on_enter(self):
|
|
||||||
with open('log.txt','a+') as of: of.write(str(dir(self)))
|
|
||||||
print(dir(self))
|
|
||||||
#self.add_widget(MDLabel(text='hello world!'))
|
|
||||||
pass
|
|
||||||
|
|
||||||
class WelcomeScreen(Screen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class PeopleScreen(Screen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class EventsScreen(Screen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class MessagesScreen(Screen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class NotificationsScreen(Screen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MainApp(MDApp):
|
|
||||||
# def build(self):
|
|
||||||
# self.theme_cls.primary_palette = "Red" # "Purple", "Red"
|
|
||||||
title = 'Gyre'
|
|
||||||
|
|
||||||
def build(self):
|
|
||||||
#self.theme_cls.primary_palette = "Green" # "Purple", "Red"
|
|
||||||
|
|
||||||
Builder.load_file('main.kv')
|
|
||||||
# self.sm = ScreenManager()
|
|
||||||
# self.sm.add_widget(BaseScreen(name='base'))
|
|
||||||
# self.sm.add_widget(FeedScreen(name='feed'))
|
|
||||||
|
|
||||||
# return self.sm
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
App = MainApp()
|
|
||||||
App.run()
|
|
@ -1,172 +0,0 @@
|
|||||||
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
|
|
||||||
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
|
|
||||||
|
|
||||||
root = None
|
|
||||||
app = None
|
|
||||||
|
|
||||||
def log(x):
|
|
||||||
with open('log.txt','a+') as of:
|
|
||||||
of.write(str(x)+'\n')
|
|
||||||
|
|
||||||
class MyLayout(BoxLayout):
|
|
||||||
scr_mngr = ObjectProperty(None)
|
|
||||||
#orientation = 'vertical'
|
|
||||||
|
|
||||||
def change_screen(self, screen, *args):
|
|
||||||
self.scr_mngr.current = screen
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.orientation='vertical'
|
|
||||||
self.add_widget(MyToolbar())
|
|
||||||
|
|
||||||
class MyIconButton(MDIconButton):
|
|
||||||
kwargs = dict(theme_text_color='Custom',text_color=(1,0,0,1),pos_hint = {'center_y': 0.5})
|
|
||||||
def __init__(self, screen_name, *args, **kwargs):
|
|
||||||
kwargs = dict(list(self.kwargs.items()) + list(kwargs.items()))
|
|
||||||
kwargs['on_release'] = lambda x: app.change_screen(screen_name)
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
class MyLabel(MDLabel):
|
|
||||||
kwargs = dict(theme_text_color='Custom',text_color=(1,0,0,1), pos_hint = {'center_y': 0.5})
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
kwargs = dict(list(self.kwargs.items()) + list(kwargs.items()))
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
class MyToolbar(MDToolbar):
|
|
||||||
|
|
||||||
def change_screen(self,x, *args, **kwargs):
|
|
||||||
app.change_screen(x)
|
|
||||||
|
|
||||||
# def __init__(self, *args, **kwargs):
|
|
||||||
# super().__init__(*args, **kwargs)
|
|
||||||
# self.id='toolbar'
|
|
||||||
# self.title='Gyre'
|
|
||||||
# self.pos_hint = {'center_x': .5, 'center_y': 0.95}
|
|
||||||
# self.md_bg_color = (0,0,0,1)
|
|
||||||
# # self.ids['left_actions'] = left = Widget()
|
|
||||||
# # self.ids['right_actions'] = right = Widget()
|
|
||||||
# # self.specific_text_color = (1,0,0,1)
|
|
||||||
|
|
||||||
|
|
||||||
# # Add icons
|
|
||||||
|
|
||||||
# self.add_widget(MyIconButton('feed', icon='radio-tower'))
|
|
||||||
# self.add_widget(MyIconButton('people', icon='account-group'))
|
|
||||||
# self.add_widget(MyIconButton('events', icon='calendar'))
|
|
||||||
# self.add_widget(MyIconButton('messages', icon='message-processing-outline'))
|
|
||||||
# self.add_widget(MyIconButton('notifications', icon='bell-outline'))
|
|
||||||
|
|
||||||
|
|
||||||
# def button_notif(self):
|
|
||||||
# return MyIconButton('notifications', icon='bell-outline')
|
|
||||||
|
|
||||||
|
|
||||||
class BaseScreen(MDScreen):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
#self.add_widget(MDLabel(text='Turning and turning in the widening gyre \nThe falcon cannot hear the falconer;\nThings fall apart; the centre cannot hold;\nMere anarchy is loosed upon the world,\nThe blood-dimmed tide is loosed, and everywhere \nThe ceremony of innocence is drowned;\nThe best lack all conviction, while the worst \nAre full of passionate intensity.\n\nSurely some revelation is at hand;\nSurely the Second Coming is at hand. \nThe Second Coming! Hardly are those words out \nWhen a vast image out of Spiritus Mundi\nTroubles my sight: somewhere in sands of the desert \nA shape with lion body and the head of a man, \nA gaze blank and pitiless as the sun, \nIs moving its slow thighs, while all about it \nReel shadows of the indignant desert birds. \nThe darkness drops again; but now I know \nThat twenty centuries of stony sleep\nWere vexed to nightmare by a rocking cradle, \nAnd what rough beast, its hour come round at last, \nSlouches towards Bethlehem to be born?'))
|
|
||||||
|
|
||||||
|
|
||||||
class FeedScreen(MDScreen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class WelcomeScreen(MDScreen):
|
|
||||||
id='welcome'
|
|
||||||
|
|
||||||
#def on_enter(self, *args, **kwargs):
|
|
||||||
# super().on_enter()
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
# self.add_widget(
|
|
||||||
# MDFillRoundFlatButton(
|
|
||||||
# text="Hello, World",
|
|
||||||
# pos_hint={"center_x": 0.5, "center_y": 0.5},
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
self.add_widget(
|
|
||||||
MyLabel(
|
|
||||||
text='Turning and turning in the widening gyre \nThe falcon cannot hear the falconer;\nThings fall apart; the centre cannot hold;\nMere anarchy is loosed upon the world,\nThe blood-dimmed tide is loosed, and everywhere \nThe ceremony of innocence is drowned;\nThe best lack all conviction, while the worst \nAre full of passionate intensity.\n\nSurely some revelation is at hand;\nSurely the Second Coming is at hand. \nThe Second Coming! Hardly are those words out \nWhen a vast image out of Spiritus Mundi\nTroubles my sight: somewhere in sands of the desert \nA shape with lion body and the head of a man, \nA gaze blank and pitiless as the sun, \nIs moving its slow thighs, while all about it \nReel shadows of the indignant desert birds. \nThe darkness drops again; but now I know \nThat twenty centuries of stony sleep\nWere vexed to nightmare by a rocking cradle, \nAnd what rough beast, its hour come round at last, \nSlouches towards Bethlehem to be born?',
|
|
||||||
halign='center'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
class PeopleScreen(MDScreen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class EventsScreen(MDScreen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class MessagesScreen(MDScreen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class NotificationsScreen(MDScreen):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MainApp(MDApp):
|
|
||||||
# def build(self):
|
|
||||||
# self.theme_cls.primary_palette = "Red" # "Purple", "Red"
|
|
||||||
title = 'Gyre'
|
|
||||||
|
|
||||||
def build1(self):
|
|
||||||
global root,app
|
|
||||||
root = MyLayout()
|
|
||||||
app = self
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.theme_cls = ThemeManager()
|
|
||||||
self.theme_cls.primary_palette='Red'
|
|
||||||
self.theme_cls.theme_style='Dark'
|
|
||||||
|
|
||||||
self.screens = OrderedDict()
|
|
||||||
self.screens['welcome']=WelcomeScreen(name='welcome')
|
|
||||||
self.screens['feed']=FeedScreen(name='feed')
|
|
||||||
self.screens['people']=PeopleScreen(name='people')
|
|
||||||
self.screens['events']=EventsScreen(name='events')
|
|
||||||
self.screens['messages']=MessagesScreen(name='messages')
|
|
||||||
self.screens['notifications']=NotificationsScreen(name='notifications')
|
|
||||||
|
|
||||||
|
|
||||||
self.sm = ScreenManager()
|
|
||||||
for screen in self.screens.values():
|
|
||||||
self.sm.add_widget(screen)
|
|
||||||
|
|
||||||
root.add_widget(self.sm)
|
|
||||||
|
|
||||||
return root
|
|
||||||
|
|
||||||
def build(self):
|
|
||||||
global root,app
|
|
||||||
app = self
|
|
||||||
root = Builder.load_file('main1.kv')
|
|
||||||
return root
|
|
||||||
|
|
||||||
def change_screen(self,x):
|
|
||||||
#log('testing2')
|
|
||||||
self.sm.switch_to(self.screens[x], transition=NoTransition())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
App = MainApp()
|
|
||||||
App.run()
|
|
@ -1,138 +0,0 @@
|
|||||||
#:import get_color_from_hex kivy.utils.get_color_from_hex
|
|
||||||
#:import images_path kivymd.images_path
|
|
||||||
#:import colors kivymd.color_definitions.colors
|
|
||||||
#:import partial functools.partial
|
|
||||||
#:import NoTransition kivy.uix.screenmanager.NoTransition
|
|
||||||
# :import MDCarousel kivymd.uix.carousel.MDCarousel
|
|
||||||
|
|
||||||
MyLayout:
|
|
||||||
scr_mngr: scr_mngr
|
|
||||||
orientation: 'vertical'
|
|
||||||
height: self.minimum_height
|
|
||||||
|
|
||||||
canvas:
|
|
||||||
Color:
|
|
||||||
rgba: 0.925,0.925,0.925,1 #get_color_from_hex(colors['Gray']['900'])
|
|
||||||
Rectangle:
|
|
||||||
pos: self.pos
|
|
||||||
size: self.size
|
|
||||||
|
|
||||||
MDToolbar:
|
|
||||||
id: toolbar
|
|
||||||
title: app.title
|
|
||||||
pos_hint: {'center_x': .5, 'center_y': 0.95}
|
|
||||||
md_bg_color: 0.1,0.1,0.1,1
|
|
||||||
background_palette: 'Red'
|
|
||||||
background_hue: '500'
|
|
||||||
specific_text_color: 1,0,0,1
|
|
||||||
right_action_items: [['radio-tower', partial(root.change_screen, 'feed')], ['account-group', partial(root.change_screen, 'people')], ['calendar', partial(root.change_screen, 'events')], ['message-processing-outline', partial(root.change_screen, 'messages')], ['bell-outline', partial(root.change_screen, 'notifications')]]
|
|
||||||
left_action_items: [[f"assets/logo.png", partial(root.change_screen, 'welcome')]]
|
|
||||||
|
|
||||||
ScreenManager:
|
|
||||||
id: scr_mngr
|
|
||||||
# transition: NoTransition()
|
|
||||||
|
|
||||||
|
|
||||||
WelcomeScreen:
|
|
||||||
name: 'welcome'
|
|
||||||
|
|
||||||
MyLabel:
|
|
||||||
text: "Turning and turning in the widening gyre \nThe falcon cannot hear the falconer;\nThings fall apart; the centre cannot hold;\nMere anarchy is loosed upon the world,\nThe blood-dimmed tide is loosed, and everywhere \nThe ceremony of innocence is drowned;\nThe best lack all conviction, while the worst \nAre full of passionate intensity.\n\nSurely some revelation is at hand;\nSurely the Second Coming is at hand. \nThe Second Coming! Hardly are those words out \nWhen a vast image out of Spiritus Mundi\nTroubles my sight: somewhere in sands of the desert \nA shape with lion body and the head of a man, \nA gaze blank and pitiless as the sun, \nIs moving its slow thighs, while all about it \nReel shadows of the indignant desert birds. \nThe darkness drops again; but now I know \nThat twenty centuries of stony sleep\nWere vexed to nightmare by a rocking cradle, \nAnd what rough beast, its hour come round at last, \nSlouches towards Bethlehem to be born?"
|
|
||||||
|
|
||||||
|
|
||||||
PeopleScreen:
|
|
||||||
name: 'people'
|
|
||||||
|
|
||||||
ScrollView:
|
|
||||||
id: scroll
|
|
||||||
size_hint: (1, 1)
|
|
||||||
pos_hint: {'center_x': .5, 'y': 0}
|
|
||||||
do_scroll_x: False
|
|
||||||
bar_width: 0
|
|
||||||
scroll_type: ['content']
|
|
||||||
|
|
||||||
MDList:
|
|
||||||
id: container
|
|
||||||
# size_hint_y: None
|
|
||||||
# height: '100dp'
|
|
||||||
#padding: 0, self._list_vertical_padding
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FeedScreen:
|
|
||||||
name: 'feed'
|
|
||||||
#MyLabel:
|
|
||||||
# text: "The falcon cannot hear the falconer..."
|
|
||||||
Carousel:
|
|
||||||
direction: 'right'
|
|
||||||
|
|
||||||
#AsyncImage:
|
|
||||||
# source:'avatar.jpg'
|
|
||||||
MDCard:
|
|
||||||
orientation: "vertical"
|
|
||||||
padding: "8dp"
|
|
||||||
size_hint: 0.9, 0.9
|
|
||||||
# md_bg_color: 1,0,0,1
|
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
text: "Counter culture is dead"
|
|
||||||
theme_text_color: "Secondary"
|
|
||||||
size_hint_y: None
|
|
||||||
height: self.texture_size[1]
|
|
||||||
font_style: 'H5'
|
|
||||||
halign: 'center'
|
|
||||||
AsyncImage:
|
|
||||||
source: 'avatar.jpg'
|
|
||||||
MDLabel:
|
|
||||||
text: "Resistance to popular music (Taylor Swift, etc) is culturally obsolete. It's no longer possible to 'counter' culture as 'bad' or aesthetically impoverished: music is good, TV is good, the internet is funny, and we're all just hooked up to the same cultural 'streams' and 'feeds'."
|
|
||||||
pos_hint: {'center_y':1}
|
|
||||||
font_style: 'Body1'
|
|
||||||
MDCard:
|
|
||||||
orientation: "vertical"
|
|
||||||
padding: "8dp"
|
|
||||||
size_hint: 0.9, 0.9
|
|
||||||
# md_bg_color: 1,0,0,1
|
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
text: "Can God compete with Adam?"
|
|
||||||
theme_text_color: "Secondary"
|
|
||||||
size_hint_y: None
|
|
||||||
height: self.texture_size[1]
|
|
||||||
font_style: 'H5'
|
|
||||||
halign: 'center'
|
|
||||||
AsyncImage:
|
|
||||||
source: 'spiral4.png'
|
|
||||||
MDLabel:
|
|
||||||
text: "The lines to break Tech up on are already there, just covered up: Amazon is both the infrastructure connecting all businesses & consumers, while at the same time competing with those businesses—using its omnipotent money and omniscient data like God 'competing' with Adam & Eve."
|
|
||||||
|
|
||||||
|
|
||||||
MDCard:
|
|
||||||
orientation: "vertical"
|
|
||||||
padding: "8dp"
|
|
||||||
size_hint: 0.9, 0.9
|
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
|
||||||
|
|
||||||
AsyncImage:
|
|
||||||
source: 'spiral4.png'
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
text: "The lines to break Tech up on are already there, just covered up: Amazon is both the infrastructure connecting all businesses & consumers, while at the same time competing with those businesses—using its omnipotent money and omniscient data like God 'competing' with Adam & Eve."
|
|
||||||
|
|
||||||
AsyncImage:
|
|
||||||
source:'spiral2.png'
|
|
||||||
AsyncImage:
|
|
||||||
source: 'spiral4.png'
|
|
||||||
|
|
||||||
|
|
||||||
EventsScreen:
|
|
||||||
name: 'events'
|
|
||||||
|
|
||||||
MessagesScreen:
|
|
||||||
name: 'messages'
|
|
||||||
|
|
||||||
NotificationsScreen:
|
|
||||||
name: 'notifications'
|
|
@ -1,146 +0,0 @@
|
|||||||
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
|
|
||||||
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 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
|
|
||||||
|
|
||||||
root = None
|
|
||||||
app = None
|
|
||||||
|
|
||||||
def log(x):
|
|
||||||
with open('log.txt','a+') as of:
|
|
||||||
of.write(str(x)+'\n')
|
|
||||||
|
|
||||||
class MyLayout(BoxLayout):
|
|
||||||
scr_mngr = ObjectProperty(None)
|
|
||||||
def change_screen(self, screen, *args):
|
|
||||||
self.scr_mngr.current = screen
|
|
||||||
|
|
||||||
|
|
||||||
class MyLabel(MDLabel):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.theme_text_color='Custom'
|
|
||||||
self.text_color=(1,0,0,1)
|
|
||||||
self.pos_hint = {'center_y': 0.5}
|
|
||||||
self.halign='center'
|
|
||||||
self.height=self.texture_size[1]
|
|
||||||
for k,v in kwargs.items(): setattr(self,k,v)
|
|
||||||
|
|
||||||
class ContactPhoto(ILeftBody, AsyncImage):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Post(TwoLineAvatarListItem):
|
|
||||||
"""
|
|
||||||
text: "Three-line item with avatar"
|
|
||||||
secondary_text: "Secondary text here"
|
|
||||||
tertiary_text: "fit more text than usual"
|
|
||||||
text_color: 1,0,0,1
|
|
||||||
theme_text_color: 'Custom'
|
|
||||||
"""
|
|
||||||
def __init__(self, title, content, *args, **kwargs):
|
|
||||||
super().__init__() #*args, **kwargs)
|
|
||||||
self.text = title
|
|
||||||
self.secondary_text = content
|
|
||||||
|
|
||||||
# self.theme_text_color='Custom'
|
|
||||||
# self.secondary_theme_text_color = 'Custom'
|
|
||||||
|
|
||||||
# self.text_color=(1,0,0,1)
|
|
||||||
# self.secondary_text_color = (1,0,0,1)
|
|
||||||
|
|
||||||
avatar = ImageLeftWidget()
|
|
||||||
avatar.source = 'avatar.jpg'
|
|
||||||
self.add_widget(avatar)
|
|
||||||
|
|
||||||
#icon = ImageRightWidget()
|
|
||||||
# icon.icon = 'messages'
|
|
||||||
|
|
||||||
#self.add_widget(icon)
|
|
||||||
|
|
||||||
class PostWrapped(BaseListItem):
|
|
||||||
"""
|
|
||||||
text: "Three-line item with avatar"
|
|
||||||
secondary_text: "Secondary text here"
|
|
||||||
tertiary_text: "fit more text than usual"
|
|
||||||
text_color: 1,0,0,1
|
|
||||||
theme_text_color: 'Custom'
|
|
||||||
"""
|
|
||||||
def __init__(self, title, content, *args, **kwargs):
|
|
||||||
super().__init__() #*args, **kwargs)
|
|
||||||
# self.text = title
|
|
||||||
# self.secondary_text = content
|
|
||||||
|
|
||||||
# # self.theme_text_color='Custom'
|
|
||||||
# # self.secondary_theme_text_color = 'Custom'
|
|
||||||
|
|
||||||
# # self.text_color=(1,0,0,1)
|
|
||||||
# # self.secondary_text_color = (1,0,0,1)
|
|
||||||
|
|
||||||
# avatar = ImageLeftWidget()
|
|
||||||
# avatar.source = 'avatar.jpg'
|
|
||||||
# self.add_widget(avatar)
|
|
||||||
self.size_hint_y=None
|
|
||||||
self.height='100dp'
|
|
||||||
avatar = ImageLeftWidget()
|
|
||||||
avatar.source = 'avatar.jpg'
|
|
||||||
self.add_widget(avatar)
|
|
||||||
# self.add_widget(MyLabel(text=title,pos_hint={'center_y': 0.85},halign='left'))
|
|
||||||
# self.add_widget(MyLabel(text=content,pos_hint={'center_y': 0.45},halign='left'))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FeedScreen(MDScreen):
|
|
||||||
def on_enter(self):
|
|
||||||
lim=25
|
|
||||||
with open('tweets.txt') as f:
|
|
||||||
for i,ln in enumerate(f):
|
|
||||||
if i>lim: break
|
|
||||||
|
|
||||||
post = Post(title=f'Marx Zuckerberg', content=ln.strip())
|
|
||||||
|
|
||||||
sep = MDSeparator()
|
|
||||||
sep.height='1dp'
|
|
||||||
|
|
||||||
root.ids.container.add_widget(post)
|
|
||||||
root.ids.container.add_widget(sep)
|
|
||||||
|
|
||||||
class WelcomeScreen(MDScreen): pass
|
|
||||||
class PeopleScreen(MDScreen): pass
|
|
||||||
class EventsScreen(MDScreen): pass
|
|
||||||
class MessagesScreen(MDScreen): pass
|
|
||||||
class NotificationsScreen(MDScreen): pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MainApp(MDApp):
|
|
||||||
title = 'Gyre'
|
|
||||||
|
|
||||||
def build(self):
|
|
||||||
global app,root
|
|
||||||
app = self
|
|
||||||
self.root = root = Builder.load_file('main.kv')
|
|
||||||
self.root.change_screen('feed')
|
|
||||||
return self.root
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
App = MainApp()
|
|
||||||
App.run()
|
|
@ -1,242 +0,0 @@
|
|||||||
#:import get_color_from_hex kivy.utils.get_color_from_hex
|
|
||||||
#:import images_path kivymd.images_path
|
|
||||||
#:import colors kivymd.color_definitions.colors
|
|
||||||
#:import partial functools.partial
|
|
||||||
#:import NoTransition kivy.uix.screenmanager.NoTransition
|
|
||||||
# :import MDCarousel kivymd.uix.carousel.MDCarousel
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## CLASS DEFS
|
|
||||||
|
|
||||||
<MyBoxLayout>:
|
|
||||||
orientation: "vertical"
|
|
||||||
pos_hint: {'center_x':0.5, 'center_y':0.5}
|
|
||||||
size_hint:0.5,0.5
|
|
||||||
padding:'10dp'
|
|
||||||
md_bg_color:0,0,0,1
|
|
||||||
canvas:
|
|
||||||
Color:
|
|
||||||
rgb: 1,0,0,2
|
|
||||||
Line:
|
|
||||||
width: 1
|
|
||||||
rectangle: (self.x, self.y, self.width, self.height)
|
|
||||||
|
|
||||||
|
|
||||||
<MyLabel>:
|
|
||||||
theme_text_color: 'Custom'
|
|
||||||
text_color: (1,0,0,1)
|
|
||||||
pos_hint: {'center_y': 0.5}
|
|
||||||
halign: 'center'
|
|
||||||
height: self.texture_size[1]
|
|
||||||
font_family: 'Courier'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<PostCard>:
|
|
||||||
id: post
|
|
||||||
orientation: "vertical"
|
|
||||||
padding: "8dp"
|
|
||||||
size_hint: (0.9, 0.9)
|
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
|
||||||
|
|
||||||
MDSeparator:
|
|
||||||
id: post_title_sep
|
|
||||||
height: '0dp'
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
id: post_title
|
|
||||||
text: self.title
|
|
||||||
size_hint_y: None
|
|
||||||
height: self.texture_size[1]
|
|
||||||
font_style: 'H5'
|
|
||||||
halign: 'center'
|
|
||||||
|
|
||||||
MDSeparator:
|
|
||||||
id: post_title_sep2
|
|
||||||
height: '25dp'
|
|
||||||
|
|
||||||
AsyncImage:
|
|
||||||
id: post_img
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
id: post_content
|
|
||||||
text: self.content
|
|
||||||
pos_hint: {'center_y':1}
|
|
||||||
font_style: 'Body1'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### LAYOUT
|
|
||||||
|
|
||||||
MyLayout:
|
|
||||||
scr_mngr: scr_mngr
|
|
||||||
orientation: 'vertical'
|
|
||||||
height: self.minimum_height
|
|
||||||
|
|
||||||
canvas:
|
|
||||||
Color:
|
|
||||||
rgba: 0.925,0.925,0.925,1 #get_color_from_hex(colors['Gray']['900'])
|
|
||||||
|
|
||||||
Rectangle:
|
|
||||||
pos: self.pos
|
|
||||||
size: self.size
|
|
||||||
source: 'assets/komrade.png'
|
|
||||||
|
|
||||||
|
|
||||||
MDToolbar:
|
|
||||||
id: toolbar
|
|
||||||
title: app.title
|
|
||||||
pos_hint: {'center_x': .5, 'center_y': 0.95}
|
|
||||||
md_bg_color: 0.1,0.1,0.1,1
|
|
||||||
background_palette: 'Red'
|
|
||||||
background_hue: '500'
|
|
||||||
specific_text_color: 1,0,0,1
|
|
||||||
# right_action_items: [['radio-tower', partial(root.change_screen, 'feed')], ['account-group', partial(root.change_screen, 'people')], ['calendar', partial(root.change_screen, 'events')], ['message-processing-outline', partial(root.change_screen, 'messages')], ['bell-outline', partial(root.change_screen, 'notifications')]]
|
|
||||||
right_action_items: [['post-outline', partial(root.change_screen, 'feed')], ['message-processing-outline', partial(root.change_screen, 'messages')], ['bell-outline', partial(root.change_screen, 'notifications')]]
|
|
||||||
left_action_items: [[f"assets/logo.png", partial(root.change_screen, 'feed')]]
|
|
||||||
|
|
||||||
ScreenManager:
|
|
||||||
id: scr_mngr
|
|
||||||
# transition: NoTransition()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###
|
|
||||||
# LOGIN SCREEN
|
|
||||||
###
|
|
||||||
|
|
||||||
LoginScreen:
|
|
||||||
name: "login"
|
|
||||||
# text: "Login"
|
|
||||||
# icon: "login"
|
|
||||||
|
|
||||||
MyBoxLayout:
|
|
||||||
id: loginbox
|
|
||||||
size_hint:0.5,0.2
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
id: username
|
|
||||||
hint_text: "username"
|
|
||||||
required: True
|
|
||||||
write_tab: False
|
|
||||||
multiline: False
|
|
||||||
helper_text_mode: "on_error"
|
|
||||||
color_mode: 'custom'
|
|
||||||
line_color_focus: 1,0,0,1
|
|
||||||
line_color_normal: 1,0,0,1
|
|
||||||
current_hint_text_color: 1,0,0,1
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
id: password
|
|
||||||
password: True
|
|
||||||
hint_text: "password"
|
|
||||||
required: True
|
|
||||||
write_tab: False
|
|
||||||
multiline: False
|
|
||||||
helper_text_mode: "on_error"
|
|
||||||
color_mode: 'custom'
|
|
||||||
line_color_focus: 1,0,0,1
|
|
||||||
line_color_normal: 1,0,0,1
|
|
||||||
current_hint_text_color: 1,0,0,1
|
|
||||||
|
|
||||||
|
|
||||||
MDBoxLayout:
|
|
||||||
id: buttonbox
|
|
||||||
size_hint_y: None
|
|
||||||
adaptive_width: True
|
|
||||||
height: dp(56)
|
|
||||||
spacing: '10dp'
|
|
||||||
pos_hint: {'center_x': .5}
|
|
||||||
|
|
||||||
MDRectangleFlatButton:
|
|
||||||
text: "login"
|
|
||||||
on_release:
|
|
||||||
app.login(username.text, password.text)
|
|
||||||
#app.root.change_screen("welcome")
|
|
||||||
theme_text_color: "Custom"
|
|
||||||
text_color: 1,0,0,1
|
|
||||||
md_bg_color: 0,0,0,1
|
|
||||||
|
|
||||||
|
|
||||||
MDRectangleFlatButton:
|
|
||||||
text: "register"
|
|
||||||
on_release:
|
|
||||||
app.register(username.text, password.text)
|
|
||||||
theme_text_color: "Custom"
|
|
||||||
text_color: 1,0,0,1
|
|
||||||
md_bg_color: 0,0,0,1
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
id: login_status
|
|
||||||
text:""
|
|
||||||
theme_text_color: 'Error'
|
|
||||||
pos_hint:{'center_x':.5}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WelcomeScreen:
|
|
||||||
name: 'welcome'
|
|
||||||
|
|
||||||
MyBoxLayout:
|
|
||||||
size_hint:0.666,0.666
|
|
||||||
|
|
||||||
#MyLabel:
|
|
||||||
# text: "Welcome!"
|
|
||||||
# font_style: "H3"
|
|
||||||
# pos_hint: {'center_y':0.85}
|
|
||||||
|
|
||||||
MyLabel:
|
|
||||||
text: "\n\nTurning and turning in the widening gyre \nThe falcon cannot hear the falconer;\nThings fall apart; the centre cannot hold;\nMere anarchy is loosed upon the world,\nThe blood-dimmed tide is loosed, and everywhere \nThe ceremony of innocence is drowned;\nThe best lack all conviction, while the worst \nAre full of passionate intensity.\n\nSurely some revelation is at hand..."
|
|
||||||
|
|
||||||
|
|
||||||
PeopleScreen:
|
|
||||||
name: 'people'
|
|
||||||
|
|
||||||
ScrollView:
|
|
||||||
id: scroll
|
|
||||||
size_hint: (1, 1)
|
|
||||||
pos_hint: {'center_x': .5, 'y': 0}
|
|
||||||
do_scroll_x: False
|
|
||||||
bar_width: 0
|
|
||||||
scroll_type: ['content']
|
|
||||||
|
|
||||||
MDList:
|
|
||||||
id: container
|
|
||||||
# size_hint_y: None
|
|
||||||
# height: '100dp'
|
|
||||||
#padding: 0, self._list_vertical_padding
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FeedScreen:
|
|
||||||
name: 'feed'
|
|
||||||
#MyLabel:
|
|
||||||
# text: "The falcon cannot hear the falconer..."
|
|
||||||
Carousel:
|
|
||||||
id: post_carousel
|
|
||||||
direction: 'right'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EventsScreen:
|
|
||||||
name: 'events'
|
|
||||||
|
|
||||||
MessagesScreen:
|
|
||||||
name: 'messages'
|
|
||||||
|
|
||||||
NotificationsScreen:
|
|
||||||
name: 'notifications'
|
|
||||||
|
|
@ -1,182 +0,0 @@
|
|||||||
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
|
|
||||||
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
|
|
||||||
Window.size = (640, 1136) #(2.65 * 200, 5.45 * 200)
|
|
||||||
|
|
||||||
|
|
||||||
root = None
|
|
||||||
app = None
|
|
||||||
|
|
||||||
def log(x):
|
|
||||||
with open('log.txt','a+') as of:
|
|
||||||
of.write(str(x)+'\n')
|
|
||||||
|
|
||||||
class MyLayout(MDBoxLayout):
|
|
||||||
scr_mngr = ObjectProperty(None)
|
|
||||||
|
|
||||||
def change_screen(self, screen, *args):
|
|
||||||
self.scr_mngr.current = screen
|
|
||||||
|
|
||||||
|
|
||||||
class MyBoxLayout(MDBoxLayout): pass
|
|
||||||
|
|
||||||
class MyLabel(MDLabel): pass
|
|
||||||
|
|
||||||
|
|
||||||
class PostCard(MDCard):
|
|
||||||
def __init__(self, title = None, img_src = None, content = None):
|
|
||||||
super().__init__()
|
|
||||||
self.orientation="vertical"
|
|
||||||
self.padding="8dp"
|
|
||||||
self.size_hint=(0.9, 0.9)
|
|
||||||
# self.md_bg_color=(1,0,0,1)
|
|
||||||
self.pos_hint = {"center_x": .5, "center_y": .5}
|
|
||||||
|
|
||||||
if title:
|
|
||||||
sep = MDSeparator()
|
|
||||||
sep.height='25dp'
|
|
||||||
self.add_widget(sep)
|
|
||||||
|
|
||||||
title = MDLabel(text=title)
|
|
||||||
# title.theme_text_color="Secondary"
|
|
||||||
title.size_hint_y=None
|
|
||||||
title.height=title.texture_size[1]
|
|
||||||
title.font_style='H5'
|
|
||||||
title.halign='center'
|
|
||||||
self.add_widget(title)
|
|
||||||
|
|
||||||
# spacing?
|
|
||||||
sep = MDSeparator()
|
|
||||||
sep.height='25dp'
|
|
||||||
self.add_widget(sep)
|
|
||||||
|
|
||||||
|
|
||||||
if img_src:
|
|
||||||
image = AsyncImage(source=img_src)
|
|
||||||
self.add_widget(image)
|
|
||||||
|
|
||||||
if content:
|
|
||||||
content=MDLabel(text=content)
|
|
||||||
content.pos_hint={'center_y':1}
|
|
||||||
content.font_style='Body1'
|
|
||||||
self.add_widget(content)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProtectedScreen(MDScreen):
|
|
||||||
def on_pre_enter(self):
|
|
||||||
global app
|
|
||||||
if not app.is_logged_in():
|
|
||||||
app.root.change_screen('login')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WelcomeScreen(ProtectedScreen): pass
|
|
||||||
class LoginScreen(MDScreen):
|
|
||||||
#def on_pre_enter(self):
|
|
||||||
# global app
|
|
||||||
# if app.is_logged_in():
|
|
||||||
# app.root.change_screen('feed')
|
|
||||||
|
|
||||||
class PeopleScreen(ProtectedScreen): pass
|
|
||||||
class EventsScreen(ProtectedScreen): pass
|
|
||||||
class MessagesScreen(ProtectedScreen): pass
|
|
||||||
class NotificationsScreen(ProtectedScreen): pass
|
|
||||||
|
|
||||||
|
|
||||||
class FeedScreen(ProtectedScreen):
|
|
||||||
def on_enter(self):
|
|
||||||
i=0
|
|
||||||
lim=5
|
|
||||||
with open('tweets.txt') as f:
|
|
||||||
for ln in f:
|
|
||||||
if ln.startswith('@') or ln.startswith('RT '): continue
|
|
||||||
i+=1
|
|
||||||
if i>lim: break
|
|
||||||
|
|
||||||
#post = Post(title=f'Marx Zuckerberg', content=ln.strip())
|
|
||||||
post = PostCard(title='Marx Zuckerberg',img_src='avatar.jpg',content=ln.strip())
|
|
||||||
print(post)
|
|
||||||
root.ids.post_carousel.add_widget(post)
|
|
||||||
|
|
||||||
|
|
||||||
class MainApp(MDApp):
|
|
||||||
title = 'Komrade'
|
|
||||||
api = 'http://localhost:5555/api'
|
|
||||||
logged_in=False
|
|
||||||
store = JsonStore('komrade.json')
|
|
||||||
login_expiry = 60 * 60 * 24 * 7 # once a week
|
|
||||||
#login_expiry = 5 # 5 seconds
|
|
||||||
|
|
||||||
def build(self):
|
|
||||||
global app,root
|
|
||||||
app = self
|
|
||||||
self.root = root = Builder.load_file('main.kv')
|
|
||||||
if not self.is_logged_in():
|
|
||||||
self.root.change_screen('login')
|
|
||||||
else:
|
|
||||||
self.root.change_screen('feed')
|
|
||||||
return self.root
|
|
||||||
|
|
||||||
def is_logged_in(self):
|
|
||||||
if self.logged_in: return True
|
|
||||||
if not self.store.exists('user'): return False
|
|
||||||
if self.store.get('user')['logged_in']:
|
|
||||||
if time.time() - self.store.get('user')['logged_in_when'] < self.login_expiry:
|
|
||||||
self.logged_in=True
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def do_login(self):
|
|
||||||
self.logged_in=True
|
|
||||||
self.store.put('user',logged_in=True,logged_in_when=time.time())
|
|
||||||
self.root.change_screen('feed')
|
|
||||||
|
|
||||||
|
|
||||||
def login(self,un,pw):
|
|
||||||
url = self.api+'/login'
|
|
||||||
res = requests.post(url, json={'name':un, 'passkey':pw})
|
|
||||||
|
|
||||||
if res.status_code==200:
|
|
||||||
self.do_login()
|
|
||||||
else:
|
|
||||||
self.root.ids.login_status.text=res.text
|
|
||||||
|
|
||||||
def register(self,un,pw):
|
|
||||||
url = self.api+'/register'
|
|
||||||
res = requests.post(url, json={'name':un, 'passkey':pw})
|
|
||||||
if res.status_code==200:
|
|
||||||
self.do_login()
|
|
||||||
else:
|
|
||||||
self.root.ids.login_status.text=res.text
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
App = MainApp()
|
|
||||||
App.run()
|
|
@ -1,316 +0,0 @@
|
|||||||
#:import get_color_from_hex kivy.utils.get_color_from_hex
|
|
||||||
#:import images_path kivymd.images_path
|
|
||||||
#:import colors kivymd.color_definitions.colors
|
|
||||||
#:import partial functools.partial
|
|
||||||
#:import NoTransition kivy.uix.screenmanager.NoTransition
|
|
||||||
# :import MDCarousel kivymd.uix.carousel.MDCarousel
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## CLASS DEFS
|
|
||||||
|
|
||||||
<MyBoxLayout>:
|
|
||||||
orientation: "vertical"
|
|
||||||
pos_hint: {'center_x':0.5, 'center_y':0.5}
|
|
||||||
size_hint:0.5,0.5
|
|
||||||
padding:'10dp'
|
|
||||||
md_bg_color:0,0,0,1
|
|
||||||
canvas:
|
|
||||||
Color:
|
|
||||||
rgb: 1,0,0,2
|
|
||||||
Line:
|
|
||||||
width: 1
|
|
||||||
rectangle: (self.x, self.y, self.width, self.height)
|
|
||||||
|
|
||||||
|
|
||||||
<MyLabel>:
|
|
||||||
theme_text_color: 'Custom'
|
|
||||||
text_color: (1,0,0,1)
|
|
||||||
pos_hint: {'center_y': 0.5}
|
|
||||||
halign: 'center'
|
|
||||||
height: self.texture_size[1]
|
|
||||||
font_family: 'Courier'
|
|
||||||
|
|
||||||
|
|
||||||
<PostTitle>:
|
|
||||||
id: post_title
|
|
||||||
text: ''
|
|
||||||
size_hint_y: None
|
|
||||||
height: self.texture_size[1]
|
|
||||||
font_style: 'H5'
|
|
||||||
halign: 'center'
|
|
||||||
height: '25'
|
|
||||||
size_hint_y: None
|
|
||||||
|
|
||||||
<PostImage>:
|
|
||||||
# height: '25'
|
|
||||||
size_hint_y: None
|
|
||||||
|
|
||||||
<PostGridLayout>:
|
|
||||||
cols: 1
|
|
||||||
size_hint: (1,None)
|
|
||||||
pos_hint: {'center_x':0.5, 'center_y':0}
|
|
||||||
md_bg_color: 1,1,0,1
|
|
||||||
height: self.minimum_height
|
|
||||||
|
|
||||||
|
|
||||||
<PostAuthorLayout>:
|
|
||||||
cols: 2
|
|
||||||
orientation: 'horizontal'
|
|
||||||
size_hint: (1,None)
|
|
||||||
# size_hint:(None,None)
|
|
||||||
# pos_hint:(None,None)
|
|
||||||
pos_hint: {'center_x':0.5, 'center_y':0}
|
|
||||||
# md_bg_color: 1,1,0,1
|
|
||||||
height: '100dp' #self.minimum_height
|
|
||||||
# radius:[20,]
|
|
||||||
# border_radius:20
|
|
||||||
|
|
||||||
<PostAuthorAvatar>:
|
|
||||||
size_hint:(None,None)
|
|
||||||
pos_hint:{'center_x':1,'x':1}
|
|
||||||
# padding:'10dp'
|
|
||||||
# canvas:
|
|
||||||
# Color:
|
|
||||||
# rgb: 1,0,0,1
|
|
||||||
# Line:
|
|
||||||
# width: 1
|
|
||||||
# rectangle: (self.x, self.y, self.width, self.height)
|
|
||||||
|
|
||||||
<PostAuthorLabel>:
|
|
||||||
id: post_author_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: 'left'
|
|
||||||
padding: ('10dp','0dp')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<PostContent>:
|
|
||||||
id: post_content
|
|
||||||
text: ''
|
|
||||||
pos_hint: {'center_y':1}
|
|
||||||
font_size:'58dp'
|
|
||||||
font_style:'H5'
|
|
||||||
#font_name: "Strengthen"
|
|
||||||
# height: '400'
|
|
||||||
size_hint_y: None
|
|
||||||
text_color:1,0,0,1
|
|
||||||
theme_text_color: 'Custom'
|
|
||||||
halign: 'left'
|
|
||||||
|
|
||||||
|
|
||||||
<PostCard>:
|
|
||||||
id: post
|
|
||||||
orientation: "vertical"
|
|
||||||
padding: "20dp"
|
|
||||||
size_hint: (0.9, None)
|
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
|
||||||
md_bg_color: (0,0,0,1)
|
|
||||||
height: self.minimum_height
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### LAYOUT
|
|
||||||
|
|
||||||
MyLayout:
|
|
||||||
scr_mngr: scr_mngr
|
|
||||||
orientation: 'vertical'
|
|
||||||
height: self.minimum_height
|
|
||||||
|
|
||||||
canvas:
|
|
||||||
Color:
|
|
||||||
rgba: 0.925,0.925,0.925,1 #get_color_from_hex(colors['Gray']['900'])
|
|
||||||
|
|
||||||
Rectangle:
|
|
||||||
pos: self.pos
|
|
||||||
size: self.size
|
|
||||||
source: 'assets/komrade2.png'
|
|
||||||
|
|
||||||
|
|
||||||
MDToolbar:
|
|
||||||
id: toolbar
|
|
||||||
title: app.title
|
|
||||||
pos_hint: {'center_x': .5, 'center_y': 0.95}
|
|
||||||
md_bg_color: 0.1,0.1,0.1,1
|
|
||||||
background_palette: 'Red'
|
|
||||||
background_hue: '500'
|
|
||||||
specific_text_color: 1,0,0,1
|
|
||||||
# right_action_items: [['radio-tower', partial(root.change_screen, 'feed')], ['account-group', partial(root.change_screen, 'people')], ['calendar', partial(root.change_screen, 'events')], ['message-processing-outline', partial(root.change_screen, 'messages')], ['bell-outline', partial(root.change_screen, 'notifications')]]
|
|
||||||
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, 'notifications')]]
|
|
||||||
#left_action_items: [[f"assets/fist2.png", partial(root.change_screen, 'feed')]]
|
|
||||||
font_context: None
|
|
||||||
font_name: f'assets/Strengthen.ttf'
|
|
||||||
|
|
||||||
|
|
||||||
ScreenManager:
|
|
||||||
id: scr_mngr
|
|
||||||
# transition: NoTransition()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###
|
|
||||||
# LOGIN SCREEN
|
|
||||||
###
|
|
||||||
|
|
||||||
LoginScreen:
|
|
||||||
name: "login"
|
|
||||||
# text: "Login"
|
|
||||||
# icon: "login"
|
|
||||||
|
|
||||||
MyBoxLayout:
|
|
||||||
id: loginbox
|
|
||||||
size_hint:0.5,0.18
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
id: username
|
|
||||||
hint_text: "username"
|
|
||||||
required: True
|
|
||||||
write_tab: False
|
|
||||||
multiline: False
|
|
||||||
helper_text_mode: "on_error"
|
|
||||||
color_mode: 'custom'
|
|
||||||
line_color_focus: 1,0,0,1
|
|
||||||
line_color_normal: 1,0,0,1
|
|
||||||
current_hint_text_color: 1,0,0,1
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
id: password
|
|
||||||
password: True
|
|
||||||
hint_text: "password"
|
|
||||||
required: True
|
|
||||||
write_tab: False
|
|
||||||
multiline: False
|
|
||||||
helper_text_mode: "on_error"
|
|
||||||
color_mode: 'custom'
|
|
||||||
line_color_focus: 1,0,0,1
|
|
||||||
line_color_normal: 1,0,0,1
|
|
||||||
current_hint_text_color: 1,0,0,1
|
|
||||||
|
|
||||||
|
|
||||||
MDBoxLayout:
|
|
||||||
id: buttonbox
|
|
||||||
size_hint_y: None
|
|
||||||
adaptive_width: True
|
|
||||||
height: '56dp'
|
|
||||||
spacing: '10dp'
|
|
||||||
pos_hint: {'center_x': .5}
|
|
||||||
|
|
||||||
MDRectangleFlatButton:
|
|
||||||
text: "login"
|
|
||||||
on_release:
|
|
||||||
app.login(username.text, password.text)
|
|
||||||
#app.root.change_screen("welcome")
|
|
||||||
theme_text_color: "Custom"
|
|
||||||
text_color: 1,0,0,1
|
|
||||||
md_bg_color: 0,0,0,1
|
|
||||||
|
|
||||||
|
|
||||||
MDRectangleFlatButton:
|
|
||||||
text: "register"
|
|
||||||
on_release:
|
|
||||||
app.register(username.text, password.text)
|
|
||||||
theme_text_color: "Custom"
|
|
||||||
text_color: 1,0,0,1
|
|
||||||
md_bg_color: 0,0,0,1
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
id: login_status
|
|
||||||
text:""
|
|
||||||
theme_text_color: 'Error'
|
|
||||||
pos_hint:{'center_x':.5}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WelcomeScreen:
|
|
||||||
name: 'welcome'
|
|
||||||
|
|
||||||
MyBoxLayout:
|
|
||||||
size_hint:0.666,0.666
|
|
||||||
|
|
||||||
#MyLabel:
|
|
||||||
# text: "Welcome!"
|
|
||||||
# font_style: "H3"
|
|
||||||
# pos_hint: {'center_y':0.85}
|
|
||||||
|
|
||||||
MyLabel:
|
|
||||||
text: "\n\nTurning and turning in the widening gyre \nThe falcon cannot hear the falconer;\nThings fall apart; the centre cannot hold;\nMere anarchy is loosed upon the world,\nThe blood-dimmed tide is loosed, and everywhere \nThe ceremony of innocence is drowned;\nThe best lack all conviction, while the worst \nAre full of passionate intensity.\n\nSurely some revelation is at hand..."
|
|
||||||
|
|
||||||
|
|
||||||
PeopleScreen:
|
|
||||||
name: 'people'
|
|
||||||
|
|
||||||
ScrollView:
|
|
||||||
id: scroll
|
|
||||||
size_hint: (1, 1)
|
|
||||||
pos_hint: {'center_x': .5, 'y': 0}
|
|
||||||
do_scroll_x: False
|
|
||||||
bar_width: 0
|
|
||||||
scroll_type: ['content']
|
|
||||||
|
|
||||||
MDList:
|
|
||||||
id: container
|
|
||||||
# size_hint_y: None
|
|
||||||
# height: '100dp'
|
|
||||||
#padding: 0, self._list_vertical_padding
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FeedScreen:
|
|
||||||
name: 'feed'
|
|
||||||
#MyLabel:
|
|
||||||
# text: "The falcon cannot hear the falconer..."
|
|
||||||
Carousel:
|
|
||||||
id: post_carousel
|
|
||||||
direction: 'right'
|
|
||||||
|
|
||||||
AddPostScreen:
|
|
||||||
name: 'post'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EventsScreen:
|
|
||||||
name: 'events'
|
|
||||||
|
|
||||||
MessagesScreen:
|
|
||||||
name: 'messages'
|
|
||||||
|
|
||||||
NotificationsScreen:
|
|
||||||
name: 'notifications'
|
|
||||||
|
|
@ -1,259 +0,0 @@
|
|||||||
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
|
|
||||||
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
|
|
||||||
|
|
||||||
Window.size = (640, 1136) #(2.65 * 200, 5.45 * 200)
|
|
||||||
|
|
||||||
|
|
||||||
root = None
|
|
||||||
app = None
|
|
||||||
|
|
||||||
def log(x):
|
|
||||||
with open('log.txt','a+') as of:
|
|
||||||
of.write(str(x)+'\n')
|
|
||||||
|
|
||||||
class MyLayout(MDBoxLayout):
|
|
||||||
scr_mngr = ObjectProperty(None)
|
|
||||||
|
|
||||||
def change_screen(self, screen, *args):
|
|
||||||
self.scr_mngr.current = screen
|
|
||||||
|
|
||||||
|
|
||||||
class MyBoxLayout(MDBoxLayout): pass
|
|
||||||
class MyLabel(MDLabel): pass
|
|
||||||
|
|
||||||
|
|
||||||
### POST CODE
|
|
||||||
class PostTitle(MDLabel): pass
|
|
||||||
class PostGridLayout(GridLayout): pass
|
|
||||||
class PostImage(AsyncImage): pass
|
|
||||||
|
|
||||||
class PostContent(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'
|
|
||||||
#pass
|
|
||||||
|
|
||||||
class PostAuthorLayout(MDBoxLayout): pass
|
|
||||||
|
|
||||||
class PostAuthorLabel(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'
|
|
||||||
pass
|
|
||||||
class PostAuthorAvatar(AsyncImage): pass
|
|
||||||
|
|
||||||
class PostCard(MDCard):
|
|
||||||
def __init__(self, author = None, title = None, img_src = None, content = None):
|
|
||||||
super().__init__()
|
|
||||||
self.author = author
|
|
||||||
self.title = title
|
|
||||||
self.img_src = img_src
|
|
||||||
self.content = content
|
|
||||||
self.bind(minimum_height=self.setter('height'))
|
|
||||||
|
|
||||||
# pieces
|
|
||||||
author_section_layout = PostAuthorLayout()
|
|
||||||
author_label = PostAuthorLabel(text=self.author)
|
|
||||||
author_label.font_size = '28dp'
|
|
||||||
author_avatar = PostAuthorAvatar(source=self.img_src)
|
|
||||||
author_section_layout.add_widget(author_avatar)
|
|
||||||
author_section_layout.add_widget(author_label)
|
|
||||||
# author_section_layout.add_widget(author_avatar)
|
|
||||||
self.add_widget(author_section_layout)
|
|
||||||
|
|
||||||
|
|
||||||
title = PostTitle(text=self.title)
|
|
||||||
# image = PostImage(source=self.img_src)
|
|
||||||
content = PostContent(text=self.content)
|
|
||||||
|
|
||||||
#content = PostContent()
|
|
||||||
|
|
||||||
# add to screen
|
|
||||||
self.add_widget(title)
|
|
||||||
# self.add_widget(image)
|
|
||||||
self.add_widget(content)
|
|
||||||
#self.add_widget(layout)
|
|
||||||
|
|
||||||
#####
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### LOGIN
|
|
||||||
|
|
||||||
class ProtectedScreen(MDScreen):
|
|
||||||
def on_pre_enter(self):
|
|
||||||
global app
|
|
||||||
if not app.is_logged_in():
|
|
||||||
app.root.change_screen('login')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WelcomeScreen(ProtectedScreen): pass
|
|
||||||
class LoginScreen(MDScreen):
|
|
||||||
#def on_pre_enter(self):
|
|
||||||
# global app
|
|
||||||
# if app.is_logged_in():
|
|
||||||
# app.root.change_screen('feed')
|
|
||||||
pass
|
|
||||||
|
|
||||||
class PeopleScreen(ProtectedScreen): pass
|
|
||||||
class AddPostScreen(ProtectedScreen): pass
|
|
||||||
class EventsScreen(ProtectedScreen): pass
|
|
||||||
class MessagesScreen(ProtectedScreen): pass
|
|
||||||
class NotificationsScreen(ProtectedScreen): pass
|
|
||||||
|
|
||||||
|
|
||||||
class FeedScreen(ProtectedScreen):
|
|
||||||
def on_enter(self):
|
|
||||||
i=0
|
|
||||||
lim=5
|
|
||||||
with open('tweets.txt') as f:
|
|
||||||
for ln in f:
|
|
||||||
if ln.startswith('@') or ln.startswith('RT '): continue
|
|
||||||
i+=1
|
|
||||||
if i>lim: break
|
|
||||||
|
|
||||||
#post = Post(title=f'Marx Zuckerberg', content=ln.strip())
|
|
||||||
post = PostCard(
|
|
||||||
author='Marx Zuckerberg',
|
|
||||||
title='',
|
|
||||||
img_src='avatar.jpg',
|
|
||||||
content=ln.strip())
|
|
||||||
print(post)
|
|
||||||
root.ids.post_carousel.add_widget(post)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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_tor_python_session():
|
|
||||||
from torpy.http.requests import TorRequests
|
|
||||||
with TorRequests() as tor_requests:
|
|
||||||
with tor_requests.get_session() as s:
|
|
||||||
return s
|
|
||||||
|
|
||||||
from kivymd.font_definitions import theme_font_styles
|
|
||||||
class MainApp(MDApp):
|
|
||||||
title = 'Komrade'
|
|
||||||
#api = 'http://localhost:5555/api'
|
|
||||||
api = 'http://128.232.229.63:5555/api'
|
|
||||||
#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_tor_proxy_session()
|
|
||||||
#return get_tor_python_session()
|
|
||||||
|
|
||||||
def build(self):
|
|
||||||
# bind
|
|
||||||
global app,root
|
|
||||||
app = self
|
|
||||||
self.root = root = Builder.load_file('main.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')
|
|
||||||
else:
|
|
||||||
self.root.change_screen('feed')
|
|
||||||
return self.root
|
|
||||||
|
|
||||||
def is_logged_in(self):
|
|
||||||
if self.logged_in: return True
|
|
||||||
if not self.store.exists('user'): return False
|
|
||||||
if self.store.get('user')['logged_in']:
|
|
||||||
if time.time() - self.store.get('user')['logged_in_when'] < self.login_expiry:
|
|
||||||
self.logged_in=True
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def do_login(self):
|
|
||||||
self.logged_in=True
|
|
||||||
self.store.put('user',logged_in=True,logged_in_when=time.time())
|
|
||||||
self.root.change_screen('feed')
|
|
||||||
|
|
||||||
|
|
||||||
def login(self,un,pw):
|
|
||||||
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})
|
|
||||||
|
|
||||||
if res.status_code==200:
|
|
||||||
self.do_login()
|
|
||||||
else:
|
|
||||||
self.root.ids.login_status.text=res.text
|
|
||||||
|
|
||||||
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.do_login()
|
|
||||||
else:
|
|
||||||
self.root.ids.login_status.text=res.text
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
App = MainApp()
|
|
||||||
App.run()
|
|
@ -1,316 +0,0 @@
|
|||||||
## 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('feed')
|
|
||||||
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})
|
|
||||||
|
|
||||||
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=[]):
|
|
||||||
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 ''
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 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:
|
|
||||||
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_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()
|
|
@ -1,333 +0,0 @@
|
|||||||
## 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()
|
|
@ -1,102 +0,0 @@
|
|||||||
#:include screens/login/login.kv
|
|
||||||
#:include screens/feed/feed.kv
|
|
||||||
#:include screens/post/post.kv
|
|
||||||
#:include screens/messages/messages.kv
|
|
||||||
#:include screens/notifications/notifications.kv
|
|
||||||
|
|
||||||
|
|
||||||
#:import get_color_from_hex kivy.utils.get_color_from_hex
|
|
||||||
#:import images_path kivymd.images_path
|
|
||||||
#:import colors kivymd.color_definitions.colors
|
|
||||||
#:import partial functools.partial
|
|
||||||
#:import NoTransition kivy.uix.screenmanager.NoTransition
|
|
||||||
# :import MDCarousel kivymd.uix.carousel.MDCarousel
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## CLASS DEFS
|
|
||||||
|
|
||||||
<MyBoxLayout>:
|
|
||||||
orientation: "vertical"
|
|
||||||
pos_hint: {'center_x':0.5, 'center_y':0.5}
|
|
||||||
size_hint:0.5,0.5
|
|
||||||
padding:'10dp'
|
|
||||||
md_bg_color:0,0,0,1
|
|
||||||
canvas:
|
|
||||||
Color:
|
|
||||||
rgb: 1,0,0,2
|
|
||||||
Line:
|
|
||||||
width: 1
|
|
||||||
rectangle: (self.x, self.y, self.width, self.height)
|
|
||||||
|
|
||||||
|
|
||||||
<MyLabel>:
|
|
||||||
theme_text_color: 'Custom'
|
|
||||||
text_color: (1,0,0,1)
|
|
||||||
pos_hint: {'center_y': 0.5}
|
|
||||||
halign: 'center'
|
|
||||||
height: self.texture_size[1]
|
|
||||||
font_family: 'Courier'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### LAYOUT
|
|
||||||
|
|
||||||
MyLayout:
|
|
||||||
scr_mngr: scr_mngr
|
|
||||||
orientation: 'vertical'
|
|
||||||
height: self.minimum_height
|
|
||||||
|
|
||||||
canvas:
|
|
||||||
Color:
|
|
||||||
rgba: 0.925,0.925,0.925,1 #get_color_from_hex(colors['Gray']['900'])
|
|
||||||
|
|
||||||
Rectangle:
|
|
||||||
pos: self.pos
|
|
||||||
size: self.size
|
|
||||||
source: 'assets/komrade2.png'
|
|
||||||
|
|
||||||
|
|
||||||
MDToolbar:
|
|
||||||
id: toolbar
|
|
||||||
title: app.title
|
|
||||||
pos_hint: {'center_x': .5, 'center_y': 0.95}
|
|
||||||
md_bg_color: 0.1,0.1,0.1,1
|
|
||||||
background_palette: 'Red'
|
|
||||||
background_hue: '500'
|
|
||||||
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, 'notifications')]]
|
|
||||||
#left_action_items: [[f"assets/fist2.png", partial(root.change_screen, 'feed')]]
|
|
||||||
font_context: None
|
|
||||||
font_name: f'assets/Strengthen.ttf'
|
|
||||||
|
|
||||||
|
|
||||||
ScreenManager:
|
|
||||||
id: scr_mngr
|
|
||||||
# transition: NoTransition()
|
|
||||||
|
|
||||||
LoginScreen:
|
|
||||||
id: login_screen
|
|
||||||
|
|
||||||
FeedScreen:
|
|
||||||
id: feed_screen
|
|
||||||
|
|
||||||
AddPostScreen:
|
|
||||||
id: add_post_screen
|
|
||||||
|
|
||||||
ViewPostScreen:
|
|
||||||
id: view_post_screen
|
|
||||||
|
|
||||||
MessagesScreen:
|
|
||||||
id: messages_screen
|
|
||||||
|
|
||||||
NotificationsScreen:
|
|
||||||
id: notifications_screen
|
|
@ -1,4 +0,0 @@
|
|||||||
# Ignore everything in this directory
|
|
||||||
*
|
|
||||||
# Except this file
|
|
||||||
!.gitignore
|
|
@ -1,4 +0,0 @@
|
|||||||
# Ignore everything in this directory
|
|
||||||
*
|
|
||||||
# Except this file
|
|
||||||
!.gitignore
|
|
Loading…
Reference in New Issue