def imprimiralchatbox(self, texto):
     new_box = MDBoxLayout(size_hint=(0.8, None), orientation='horizontal', height=50, pos_hint={'x': 0.2})
     new_box.add_widget(WidgetCreator.newlabel(texto, valign='middle', halign='right', size_hint=(1.0, None)))
     with new_box.canvas.before:
         Color(usermessagebubblecolor[0], usermessagebubblecolor[1], usermessagebubblecolor[2])
         new_box.rect = RoundedRectangle(size=new_box.size, pos=new_box.pos, radius=[25, 0, 25, 25])
     new_box.bind(pos=WidgetCreator.update_rect, size=WidgetCreator.update_rect)
     self.layout.chatbox.content.add_widget(new_box)
 def establecerfase(self, fase: Fase):
     self.layout.faselabel.text = fase.nombre
     new_box = MDBoxLayout(size_hint=(0.8, None), orientation='horizontal', height=50)
     new_box.add_widget(WidgetCreator.newlabel(fase.texto, size_hint=(1.0, None), valign='middle'))
     with new_box.canvas.before:
         Color(botmessagebubblecolor[0], botmessagebubblecolor[1], botmessagebubblecolor[2])
         new_box.rect = RoundedRectangle(size=new_box.size, pos=new_box.pos, radius=[0, 25, 25, 25])
     new_box.bind(pos=WidgetCreator.update_rect, size=WidgetCreator.update_rect)
     self.layout.chatbox.content.add_widget(new_box)
 def __init__(self, **kwargs):
     super(ChatBox, self).__init__(**kwargs)
     self.do_scroll_x = False
     self.do_scroll_y = True
     new_box = BoxLayout(size_hint_y=None, orientation='vertical', padding=chatboxpadding, spacing=10)
     new_box.bind(minimum_height=new_box.setter('height'))
     with self.canvas.before:
         Color(subdivisionColor[0], subdivisionColor[1], subdivisionColor[2])
         self.rect = RoundedRectangle(size=self.size, pos=self.pos, radius=[10])
     # listen to size and position changes
     self.bind(pos=WidgetCreator.update_rect, size=WidgetCreator.update_rect)
     self.content = new_box
     self.add_widget(self.content)
Ejemplo n.º 4
0
class DiscoveryMixin():
    def makeDiscoveryPage(self):

        # Discovery Page

        screen = Screen(name='Discovery')
        self.discoveryScreen = screen

        layout = BoxLayout(orientation='vertical', spacing=10)
        screen.add_widget(layout)

        label = Label(
            size_hint=(1, None),
            halign="center",
            text=
            'Browsing your local network.\nWarning: anyone on your network\ncan advertise a site with any title they want.'
        )

        layout.add_widget(self.makeBackButton())

        layout.add_widget(label)

        self.discoveryScroll = ScrollView(size_hint=(1, 1))

        self.discoveryListbox = BoxLayout(orientation='vertical',
                                          size_hint=(1, None))
        self.discoveryListbox.bind(
            minimum_height=self.discoveryListbox.setter('height'))

        self.discoveryScroll.add_widget(self.discoveryListbox)
        layout.add_widget(self.discoveryScroll)

        return screen

    def goToDiscovery(self, *a):
        "Go to the local network discovery page"
        self.discoveryListbox.clear_widgets()

        try:
            hardline.discoveryPeer.search('', n=1)
            time.sleep(2)
            for i in hardline.getAllDiscoveries():
                info = i

                self.discoveryListbox.add_widget(
                    MDToolbar(title=str(info.get('title', 'no title'))))
                l = StackLayout(adaptive_size=True,
                                spacing=8,
                                size_hint=(1, None))

                #Need to capture that info in the closures
                def scope(info):
                    btn = Button(text="Open in Browser")

                    def f(*a):
                        self.openInBrowser("http://" + info['hash'] +
                                           ".localhost:7009")

                    btn.bind(on_press=f)

                    l.add_widget(btn)

                    btn = Button(text="Copy URL")

                    def f(*a):
                        try:
                            from kivy.core.clipboard import Clipboard
                            Clipboard.copy("http://" + info['hash'] +
                                           ".localhost:7009")
                        except:
                            logging.exception("Could not copy to clipboard")

                    btn.bind(on_press=f)

                    self.localServicesListBox.add_widget(
                        MDToolbar(title=str(info.get('title', 'no title'))))

                    l.add_widget(btn)

                scope(info)

                self.discoveryListbox.add_widget(l)
                lb = self.saneLabel("Hosted By: " + info.get("from_ip", ""),
                                    self.discoveryListbox)
                self.discoveryListbox.add_widget(lb)
                lb = self.saneLabel("ID: " + info['hash'],
                                    self.discoveryListbox)
                self.discoveryListbox.add_widget(lb)

        except Exception:
            logging.info(traceback.format_exc())

        self.screenManager.current = "Discovery"
Ejemplo n.º 5
0
class ToolsAndSettingsMixin():
    def goToSettings(self, *a):
        self.screenManager.current = "Settings"

    def goToGlobalSettings(self, *a):
        if os.path.exists(hardline.globalSettingsPath):
            with open(hardline.globalSettingsPath) as f:
                globalConfig = toml.load(f)
        else:
            globalConfig = {}

        self.localSettingsBox.clear_widgets()

        self.localSettingsBox.add_widget(
            Label(size_hint=(1, 6), halign="center", text='OpenDHT Proxies'))
        self.localSettingsBox.add_widget(
            Label(size_hint=(1, None),
                  text='Proxies are tried in order from 1-3'))

        self.localSettingsBox.add_widget(
            self.settingButton(globalConfig, "DHTProxy", 'server1'))
        self.localSettingsBox.add_widget(
            self.settingButton(globalConfig, "DHTProxy", 'server2'))
        self.localSettingsBox.add_widget(
            self.settingButton(globalConfig, "DHTProxy", 'server3'))

        self.localSettingsBox.add_widget(
            Label(size_hint=(1, 6), halign="center", text='Stream Server'))
        self.localSettingsBox.add_widget(
            Label(
                size_hint=(1, None),
                text=
                'To allow others to sync to this node as a DrayerDB Stream server, set a server title to expose a service'
            ))

        self.localSettingsBox.add_widget(
            self.settingButton(globalConfig, "DrayerDB", 'serverName'))

        btn1 = Button(text='Save')

        def save(*a):
            with open(hardline.globalSettingsPath, 'w') as f:
                toml.dump(globalConfig, f)
            if platform == 'android':
                self.stop_service()
                self.start_service()
            else:
                daemonconfig.loadDrayerServerConfig()

            self.screenManager.current = "Main"

        btn1.bind(on_press=save)
        self.localSettingsBox.add_widget(btn1)
        self.screenManager.current = "GlobalSettings"

    def makeGlobalSettingsPage(self):

        screen = Screen(name='GlobalSettings')
        layout = BoxLayout(orientation='vertical', spacing=10)
        screen.add_widget(layout)

        layout.add_widget(self.makeBackButton())

        self.localSettingsScroll = ScrollView(size_hint=(1, 1))
        self.localSettingsBox = BoxLayout(orientation='vertical',
                                          size_hint=(1, None),
                                          spacing=10)
        self.localSettingsBox.bind(
            minimum_height=self.localSettingsBox.setter('height'))

        self.localSettingsScroll.add_widget(self.localSettingsBox)

        layout.add_widget(self.localSettingsScroll)

        return screen

    def makeSettingsPage(self):
        page = Screen(name='Settings')

        layout = BoxLayout(orientation='vertical')
        page.add_widget(layout)
        label = MDToolbar(title="Settings and Tools")
        layout.add_widget(label)

        layout.add_widget(self.makeBackButton())

        log = Button(text='System Logs')

        btn1 = Button(text='Local Services')
        label1 = Label(halign="center",
                       text='Share a local webservice with the world')

        log.bind(on_release=self.gotoLogs)
        btn1.bind(on_press=self.goToLocalServices)
        layout.add_widget(log)

        layout.add_widget(btn1)
        layout.add_widget(label1)

        btn = Button(text='Global Settings')

        btn.bind(on_press=self.goToGlobalSettings)
        layout.add_widget(btn)

        # Start/Stop
        btn3 = Button(text='Stop')
        btn3.bind(on_press=self.stop_service)
        label3 = Label(
            size_hint=(1, None),
            halign="center",
            text=
            'Stop the background process.  It must be running to acess hardline sites.  Starting may take a few seconds.'
        )
        layout.add_widget(btn3)
        layout.add_widget(label3)

        btn4 = Button(text='Start or Restart.')
        btn4.bind(on_press=self.start_service)
        label4 = Label(
            size_hint=(1, None),
            halign="center",
            text='Restart the process. It will show in your notifications.')
        layout.add_widget(btn4)
        layout.add_widget(label4)

        layout.add_widget(Widget())

        return page

    def makeLogsPage(self):
        screen = Screen(name='Logs')
        self.servicesScreen = screen

        layout = BoxLayout(orientation='vertical', spacing=10)
        screen.add_widget(layout)

        layout.add_widget(MDToolbar(title="System Logs"))

        layout.add_widget(self.makeBackButton())

        self.logsListBoxScroll = ScrollView(size_hint=(1, 1))

        self.logsListBox = BoxLayout(orientation='vertical',
                                     size_hint=(1, None),
                                     spacing=10)
        self.logsListBox.bind(minimum_height=self.logsListBox.setter('height'))

        self.logsListBoxScroll.add_widget(self.logsListBox)

        layout.add_widget(self.logsListBoxScroll)

        return screen

    def gotoLogs(self, *a):
        self.logsListBox.clear_widgets()
        try:
            from kivy.logger import LoggerHistory
            for i in LoggerHistory.history:
                self.logsListBox.add_widget(
                    MDTextField(text=str(i.getMessage()),
                                multiline=True,
                                size_hint=(1, None),
                                mode="rectangle"))

            self.screenManager.current = "Logs"
        except Exception as e:
            logging.info(traceback.format_exc())
Ejemplo n.º 6
0
class StreamsMixin():

    #Reuse the same panel for editStream, the main hub for accessing the stream,
    #and it's core settings
    def editStream(self, name):
        if not name in daemonconfig.userDatabases:
            self.goToStreams()
        db = daemonconfig.userDatabases[name]
        c = db.config
        try:
            c.add_section("Service")
        except:
            pass
        try:
            c.add_section("Info")
        except:
            pass

        self.streamEditPanel.clear_widgets()
        topbar = BoxLayout(size_hint=(1, None),
                           adaptive_height=True,
                           spacing=5)

        stack = StackLayout(size_hint=(1, None),
                            adaptive_height=True,
                            spacing=5)

        def upOne(*a):
            self.goToStreams()

        btn1 = Button(text='Up')

        btn1.bind(on_press=upOne)

        topbar.add_widget(btn1)

        topbar.add_widget(self.makeBackButton())

        self.streamEditPanel.add_widget(topbar)
        self.streamEditPanel.add_widget(MDToolbar(title=name))

        def goHere():
            self.editStream(name)

        self.backStack.append(goHere)
        self.backStack = self.backStack[-50:]

        btn2 = Button(text='Notebook View')

        def goPosts(*a):
            self.gotoStreamPosts(name)

        btn2.bind(on_press=goPosts)
        stack.add_widget(btn2)

        btn2 = Button(text='Feed View')

        def goPosts(*a):
            self.gotoStreamPosts(name, parent=None)

        btn2.bind(on_press=goPosts)
        stack.add_widget(btn2)

        btn2 = Button(text='Stream Settings')

        def goSettings(*a):
            self.editStreamSettings(name)

        btn2.bind(on_press=goSettings)
        stack.add_widget(btn2)

        if name.startswith('file:'):
            btn2 = Button(text='Close Stream')

            def close(*a):
                daemonconfig.closeUserDatabase(name)
                self.goToStreams()

            btn2.bind(on_press=close)
            stack.add_widget(btn2)

        importData = Button(text="Import Data File")

        def promptSet(*a):
            try:
                #Needed for android
                self.getPermission('files')
            except:
                logging.exception("cant ask permission")

            def f(selection):
                if selection:

                    def f2(x):
                        if x:
                            with daemonconfig.userDatabases[name]:
                                with open(selection) as f:
                                    daemonconfig.userDatabases[
                                        name].importFromToml(f.read())
                            daemonconfig.userDatabases[name].commit()

                    self.askQuestion("Really import?", "yes", cb=f2)
                self.openFM.close()

            from .kivymdfmfork import MDFileManager
            from . import directories
            self.openFM = MDFileManager(select_path=f)

            if os.path.exists("/storage/emulated/0/Documents") and os.access(
                    "/storage/emulated/0/Documents", os.W_OK):
                self.openFM.show("/storage/emulated/0/Documents")
            elif os.path.exists(
                    os.path.expanduser("~/Documents")) and os.access(
                        os.path.expanduser("~/Documents"), os.W_OK):
                self.openFM.show(os.path.expanduser("~/Documents"))
            else:
                self.openFM.show(directories.externalStorageDir
                                 or directories.settings_path)

        importData.bind(on_release=promptSet)
        stack.add_widget(importData)

        export = Button(text="Export All Posts")

        def promptSet(*a):
            from .kivymdfmfork import MDFileManager
            from .. import directories
            try:
                #Needed for android
                self.getPermission('files')
            except:
                logging.exception("cant ask permission")

            def f(selection):
                if selection:
                    if not selection.endswith(".toml"):
                        selection = selection + ".toml"

                    def g(a):
                        if a == 'yes':

                            r = daemonconfig.userDatabases[
                                name].getDocumentsByType('post', parent='')
                            data = daemonconfig.userDatabases[
                                name].exportRecordSetToTOML(
                                    [i['id'] for i in r])

                            logging.info("Exporting data to:" + selection)
                            with open(selection, 'w') as f:
                                f.write(data)
                        self.openFM.close()

                    if os.path.exists(selection):
                        self.askQuestion("Overwrite?", 'yes', g)
                    else:
                        g('yes')

            #Autocorrect had some fun with the kivymd devs
            self.openFM = MDFileManager(select_path=f,
                                        save_mode=(name + '.toml'))

            if os.path.exists("/storage/emulated/0/Documents") and os.access(
                    "/storage/emulated/0/Documents", os.W_OK):
                self.openFM.show("/storage/emulated/0/Documents")
            elif os.path.exists(
                    os.path.expanduser("~/Documents")) and os.access(
                        os.path.expanduser("~/Documents"), os.W_OK):
                self.openFM.show(os.path.expanduser("~/Documents"))
            else:
                self.openFM.show(directories.externalStorageDir
                                 or directories.settings_path)

        export.bind(on_release=promptSet)

        stack.add_widget(export)

        self.streamEditPanel.add_widget(stack)

        #Show recent changes no matter where they are in the tree.
        #TODO needs to be hideable for anti-spoiler purposes in fiction.
        self.streamEditPanel.add_widget(MDToolbar(title="Recent Changes:"))

        for i in daemonconfig.userDatabases[name].getDocumentsByType(
                'post', orderBy='arrival DESC', limit=5):
            x = self.makePostWidget(name, i, includeParent=True)
            self.streamEditPanel.add_widget(x)

        self.screenManager.current = "EditStream"

    def showSharingCode(self, name, c, wp=True):
        if daemonconfig.ddbservice[0]:
            try:
                localServer = daemonconfig.ddbservice[0].getSharableURL()
            except:
                logging.exception("wtf")
        else:
            localServer = ''

        d = {
            'sv': c['Sync'].get('server', '') or localServer,
            'vk': c['Sync'].get("syncKey", ''),
            'n': name[:24]
        }
        if wp:
            d['sk'] = c['Sync'].get('writePassword', '')
        else:
            d['sk'] = ''

        import json
        d = json.dumps(d, indent=0, separators=(',', ':'))
        if wp:
            self.showQR(d, "Stream Code(full access)")
        else:
            self.showQR(d, "Stream Code(readonly)")

    def editStreamSettings(self, name):
        db = daemonconfig.userDatabases[name]
        c = db.config

        self.streamEditPanel.clear_widgets()

        self.streamEditPanel.add_widget(
            Label(size_hint=(1, None), halign="center", text=name))
        self.streamEditPanel.add_widget(
            Label(size_hint=(1, None),
                  halign="center",
                  text="file:" + db.filename))

        self.streamEditPanel.add_widget(self.makeBackButton())

        def save(*a):
            logging.info("SAVE BUTTON WAS PRESSED")
            # On android this is the bg service's job
            db.saveConfig()

            if platform == 'android':
                self.stop_service()
                self.start_service()
            else:
                db.close()
                daemonconfig.loadUserDatabases(
                    None,
                    only=name,
                    callbackFunction=self.onDrayerRecordChange)

        def delete(*a):
            def f(n):
                if n and n == name:
                    daemonconfig.delDatabase(None, n)
                    if platform == 'android':
                        self.stop_service()
                        self.start_service()
                    self.goToStreams()

            self.askQuestion("Really delete?", name, f)

        self.streamEditPanel.add_widget(
            Label(size_hint=(1, None),
                  halign="center",
                  font_size="24sp",
                  text='Sync'))

        self.streamEditPanel.add_widget(
            keyBox := self.settingButton(c, "Sync", "syncKey"))

        self.streamEditPanel.add_widget(
            pBox := self.settingButton(c, "Sync", "writePassword"))

        self.streamEditPanel.add_widget(
            Label(
                size_hint=(1, None),
                halign="center",
                font_size="12sp",
                text=
                'Keys have a special format, you must use the generator to change them.'
            ))

        def promptNewKeys(*a, **k):
            def makeKeys(a):
                if a == 'yes':
                    import base64
                    vk, sk = libnacl.crypto_sign_keypair()
                    vk = base64.b64encode(vk).decode()
                    sk = base64.b64encode(sk).decode()
                    keyBox.text = vk
                    pBox.text = sk

            self.askQuestion("Overwrite with random keys?", 'yes', makeKeys)

        keyButton = Button(text='Generate New Keys')
        keyButton.bind(on_press=promptNewKeys)
        self.streamEditPanel.add_widget(keyButton)

        self.streamEditPanel.add_widget(
            serverBox := self.settingButton(c, "Sync", "server"))

        self.streamEditPanel.add_widget(
            Label(size_hint=(1, None),
                  halign="center",
                  text='Do not include the http:// '))

        self.streamEditPanel.add_widget(
            self.settingButton(c, "Sync", "serve", 'yes'))

        self.streamEditPanel.add_widget(
            Label(size_hint=(1, None),
                  halign="center",
                  text='Set serve=no to forbid clients to sync'))

        self.streamEditPanel.add_widget(
            Label(size_hint=(1, None),
                  halign="center",
                  font_size="24sp",
                  text='Application'))

        self.streamEditPanel.add_widget(
            self.settingButton(c, "Application", "notifications", 'no'))

        def f(*a):
            def g(a):
                try:
                    import json
                    a = json.loads(a)
                    serverBox.text = c['Sync'][
                        'server'] = a['sv'] or c['Sync']['server']
                    keyBox.text = c['Sync']['syncKey'] = a['vk']
                    pBox.text = c['Sync']['writePassword'] = a['sk']

                except:
                    pass

            self.askQuestion("Enter Sharing Code", cb=g, multiline=True)

        keyButton = Button(text='Load from Code')
        keyButton.bind(on_press=f)
        self.streamEditPanel.add_widget(keyButton)

        def f(*a):
            self.showSharingCode(name, c)

        keyButton = Button(text='Show Sharing Code')
        keyButton.bind(on_press=f)
        self.streamEditPanel.add_widget(keyButton)

        def f(*a):
            self.showSharingCode(name, c, wp=False)

        keyButton = Button(text='Readonly Sharing Code')
        keyButton.bind(on_press=f)
        self.streamEditPanel.add_widget(keyButton)

        btn1 = Button(text='Save Changes')

        btn1.bind(on_press=save)
        self.streamEditPanel.add_widget(btn1)

        btn2 = Button(text='Delete this stream')

        btn2.bind(on_press=delete)
        self.streamEditPanel.add_widget(btn2)

        def gotoOrphans(*a, **k):
            self.gotoStreamPosts(name, orphansMode=True)

        oButton = Button(text='Show Unreachable Garbage')
        oButton.bind(on_press=gotoOrphans)
        self.streamEditPanel.add_widget(oButton)

        noSpreadsheet = Button(text="Spreadsheet on/off")

        def promptSet(*a):
            from .kivymdfmfork import MDFileManager
            from .. import directories
            try:
                #Needed for android
                self.getPermission('files')
            except:
                logging.exception("cant ask permission")

            def f(selection):
                if selection == 'on':
                    daemonconfig.userDatabases[
                        name].enableSpreadsheetEval = True
                else:
                    daemonconfig.userDatabases[
                        name].enableSpreadsheetEval = False

            if hasattr(daemonconfig.userDatabases[name],
                       'enableSpreadsheetEval'):
                esf = daemonconfig.userDatabases[name].enableSpreadsheetEval
            else:
                esf = True

            self.askQuestion("Allow Spreadsheet Functions?",
                             'on' if esf else 'off', f)

        noSpreadsheet.bind(on_release=promptSet)
        self.streamEditPanel.add_widget(noSpreadsheet)
        self.streamEditPanel.add_widget(
            self.saneLabel(
                "Disabling only takes effect for this session. Use this feature if a stream is loading too slowly, to allow you to fix the offending expression.",
                self.streamEditPanel))

        self.screenManager.current = "EditStream"

    def makeStreamsPage(self):
        "Prettu much just an empty page filled in by the specific goto functions"

        screen = Screen(name='Streams')
        self.servicesScreen = screen

        self.streamsEditPanelScroll = ScrollView(size_hint=(1, 1))

        self.streamsEditPanel = BoxLayout(orientation='vertical',
                                          adaptive_height=True,
                                          spacing=5,
                                          size_hint=(1, None))
        self.streamsEditPanel.bind(
            minimum_height=self.streamsEditPanel.setter('height'))

        self.streamsEditPanelScroll.add_widget(self.streamsEditPanel)

        screen.add_widget(self.streamsEditPanelScroll)

        return screen

    def goToStreams(self, *a):

        "Go to a page wherein we can list user-modifiable services."
        self.streamsEditPanel.clear_widgets()

        layout = self.streamsEditPanel

        bar = BoxLayout(spacing=10, adaptive_height=True, size_hint=(1, None))

        stack = StackLayout(spacing=10,
                            adaptive_height=True,
                            size_hint=(1, None))
        layout.add_widget(bar)
        layout.add_widget(MDToolbar(title="My Streams"))

        layout.add_widget(stack)

        def upOne(*a):
            self.gotoMainScreen()

        btn1 = Button(text='Up')

        btn1.bind(on_press=upOne)

        bar.add_widget(btn1)
        bar.add_widget(self.makeBackButton())

        btn2 = Button(text='Create a Stream')

        btn2.bind(on_press=self.promptAddStream)
        stack.add_widget(btn2)

        def f(selection):
            if selection:
                dn = 'file:' + os.path.basename(selection)
                while dn in daemonconfig.userDatabases:
                    dn = dn + '2'
                try:
                    daemonconfig.loadUserDatabase(selection, dn)
                    self.editStream(dn)
                except:
                    logging.exception(dn)

            self.openFM.close()

        #This lets us view notebook files that aren't installed.
        def promptOpen(*a):

            try:
                #Needed for android
                self.getPermission('files')
            except:
                logging.exception("cant ask permission")

            from .kivymdfmfork import MDFileManager
            from . import directories
            self.openFM = MDFileManager(select_path=f)

            if os.path.exists("/storage/emulated/0/Documents") and os.access(
                    "/storage/emulated/0/Documents", os.W_OK):
                self.openFM.show("/storage/emulated/0/Documents")
            elif os.path.exists(
                    os.path.expanduser("~/Documents")) and os.access(
                        os.path.expanduser("~/Documents"), os.W_OK):
                self.openFM.show(os.path.expanduser("~/Documents"))
            else:
                self.openFM.show(directories.externalStorageDir
                                 or directories.settings_path)

        btn1 = Button(text='Open Book File')

        btn1.bind(on_press=promptOpen)

        stack.add_widget(btn1)

        def goHere():
            self.screenManager.current = "Streams"

        self.backStack.append(goHere)
        self.backStack = self.backStack[-50:]

        layout.add_widget(MDToolbar(title="Open Streams:"))

        try:
            s = daemonconfig.userDatabases
            time.sleep(0.5)
            for i in s:
                layout.add_widget(self.makeButtonForStream(i))
                try:
                    for j in daemonconfig.userDatabases[i].connectedServers:
                        if daemonconfig.userDatabases[i].connectedServers[
                                j] > (time.time() - (10 * 60)):
                            w = 'online'
                        else:
                            w = 'idle/offline'
                        layout.add_widget(
                            self.saneLabel(j[:28] + ": " + w, layout))
                except:
                    logging.exception("Error showing node status")

        except Exception:
            logging.info(traceback.format_exc())

        self.screenManager.current = "Streams"

    def makeButtonForStream(self, name):
        "Make a button that, when pressed, edits the stream in the title"

        btn = Button(text=name)

        def f(*a):
            self.editStream(name)

        btn.bind(on_press=f)
        return btn

    def promptAddStream(self, *a, **k):
        def f(v):
            if v:
                daemonconfig.makeUserDatabase(None, v)
                self.editStream(v)

        self.askQuestion("New Stream Name?", cb=f)

    def makeStreamEditPage(self):
        "Prettu much just an empty page filled in by the specific goto functions"

        screen = Screen(name='EditStream')
        self.servicesScreen = screen

        self.streamEditPanelScroll = ScrollView(size_hint=(1, 1))

        self.streamEditPanel = BoxLayout(orientation='vertical',
                                         adaptive_height=True,
                                         spacing=5,
                                         size_hint=(1, None))
        self.streamEditPanel.bind(
            minimum_height=self.streamEditPanel.setter('height'))

        self.streamEditPanelScroll.add_widget(self.streamEditPanel)

        screen.add_widget(self.streamEditPanelScroll)

        return screen
Ejemplo n.º 7
0
class ServicesMixin():
    def makeLocalServiceEditPage(self):

        screen = Screen(name='EditLocalService')
        self.servicesScreen = screen

        layout = BoxLayout(orientation='vertical', spacing=10)
        screen.add_widget(layout)
        self.localServiceEditorName = Label(size_hint=(1, None),
                                            halign="center",
                                            text="??????????")

        layout.add_widget(self.makeBackButton())

        self.localServiceEditPanelScroll = ScrollView(size_hint=(1, 1))

        self.localServiceEditPanel = BoxLayout(orientation='vertical',
                                               size_hint=(1, None))
        self.localServiceEditPanel.bind(
            minimum_height=self.localServiceEditPanel.setter('height'))

        self.localServiceEditPanelScroll.add_widget(self.localServiceEditPanel)

        layout.add_widget(self.localServiceEditPanelScroll)

        return screen

    def editLocalService(self, name, c=None):
        if not c:
            c = configparser.RawConfigParser(
                dict_type=cidict.CaseInsensitiveDict)

        try:
            c.add_section("Service")
        except:
            pass
        try:
            c.add_section("Info")
        except:
            pass

        self.localServiceEditPanel.clear_widgets()

        self.localServiceEditorName.text = name

        def save(*a):
            logging.info("SAVE BUTTON WAS PRESSED")
            # On android this is the bg service's job
            daemonconfig.makeUserService(
                None,
                name,
                title=c['Info'].get("title", 'Untitled'),
                service=c['Service'].get("service", ""),
                port=c['Service'].get("port", ""),
                cacheInfo=c['Cache'],
                noStart=(platform == 'android'),
                useDHT=c['Access'].get("useDHT", "yes"))
            if platform == 'android':
                self.stop_service()
                self.start_service()

            self.goToLocalServices()

        def delete(*a):
            def f(n):
                if n and n == name:
                    daemonconfig.delUserService(None, n)
                    if platform == 'android':
                        self.stop_service()
                        self.start_service()
                    self.goToLocalServices()

            self.askQuestion("Really delete?", name, f)

        self.localServiceEditPanel.add_widget(
            Label(size_hint=(1, None), halign="center", text='Service'))

        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Service", "service"))
        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Service", "port"))
        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Info", "title"))

        self.localServiceEditPanel.add_widget(
            Label(size_hint=(1, None), halign="center", text='Cache'))
        self.localServiceEditPanel.add_widget(
            Label(size_hint=(1, None),
                  text='Cache mode only works for static content'))

        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Cache", "directory"))

        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Cache", "maxAge"))

        self.localServiceEditPanel.add_widget(
            Label(size_hint=(1, None),
                  text='Try to refresh after maxAge seconds(default 1 week)'))

        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Cache", "maxSize", '256'))

        self.localServiceEditPanel.add_widget(
            Label(size_hint=(1, None),
                  text='Max size to use for the cache in MB'))

        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Cache", "downloadRateLimit", '1200'))

        self.localServiceEditPanel.add_widget(
            Label(size_hint=(1, None), text='Max MB per hour to download'))

        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Cache", "dynamicContent", 'no'))

        self.localServiceEditPanel.add_widget(
            Label(
                size_hint=(1, None),
                text=
                'Allow executing code in protected @mako files in the cache dir. yes to enable. Do not use with untrusted @mako'
            ))

        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Cache", "allowListing", 'no'))

        self.localServiceEditPanel.add_widget(
            Label(size_hint=(1, None),
                  text='Allow directory listing of cached content'))

        self.localServiceEditPanel.add_widget(
            Label(
                size_hint=(1, None),
                text=
                'Directory names are subfolders within the HardlineP2P cache folder,\nand can also be used to share\nstatic files by leaving the service blank.'
            ))

        self.localServiceEditPanel.add_widget(
            Label(size_hint=(1, None), halign="center",
                  text='Access Settings'))
        self.localServiceEditPanel.add_widget(
            Label(size_hint=(1, None),
                  text='Cache mode only works for static content'))

        self.localServiceEditPanel.add_widget(
            self.settingButton(c, "Access", "useDHT", 'yes'))

        self.localServiceEditPanel.add_widget(
            Label(
                size_hint=(1, None),
                text=
                'DHT Discovery uses a proxy server on Android. \nDisabling this saves bandwidth but makes access from outside your network\nunreliable.'
            ))

        btn1 = Button(text='Save Changes')

        btn1.bind(on_press=save)
        self.localServiceEditPanel.add_widget(btn1)

        btn2 = Button(text='Delete this service')

        btn2.bind(on_press=delete)
        self.localServiceEditPanel.add_widget(btn2)

        self.screenManager.current = "EditLocalService"

    def makeButtonForLocalService(self, name, c=None):
        "Make a button that, when pressed, edits the local service in the title"

        btn = Button(text=name)

        def f(*a):
            self.editLocalService(name, c)

        btn.bind(on_press=f)

        return btn

    def makeLocalServicesPage(self):

        screen = Screen(name='LocalServices')
        self.servicesScreen = screen

        layout = BoxLayout(orientation='vertical', spacing=10)
        screen.add_widget(layout)

        label = Label(
            size_hint=(1, None),
            halign="center",
            text=
            'WARNING: Running a local service may use a lot of data and battery.\nChanges may require service restart.'
        )

        labelw = Label(
            size_hint=(1, None),
            halign="center",
            text=
            'WARNING 2: This app currently prefers the external SD card for almost everything including the keys.'
        )

        layout.add_widget(self.makeBackButton())

        layout.add_widget(label)
        layout.add_widget(labelw)

        btn2 = Button(text='Create a service')

        btn2.bind(on_press=self.promptAddService)
        layout.add_widget(btn2)

        self.localServicesListBoxScroll = ScrollView(size_hint=(1, 1))

        self.localServicesListBox = BoxLayout(orientation='vertical',
                                              size_hint=(1, None),
                                              spacing=10)
        self.localServicesListBox.bind(
            minimum_height=self.localServicesListBox.setter('height'))

        self.localServicesListBoxScroll.add_widget(self.localServicesListBox)

        layout.add_widget(self.localServicesListBoxScroll)

        return screen

    def promptAddService(self, *a, **k):
        def f(v):
            if v:
                self.editLocalService(v)

        self.askQuestion("New Service filename?", cb=f)

    def goToLocalServices(self, *a):
        "Go to a page wherein we can list user-modifiable services."
        self.localServicesListBox.clear_widgets()

        try:
            s = daemonconfig.listServices(None)
            time.sleep(0.5)
            for i in s:
                self.localServicesListBox.add_widget(
                    self.makeButtonForLocalService(i, s[i]))

        except Exception:
            logging.info(traceback.format_exc())

        self.screenManager.current = "LocalServices"
    def __init__(self, resultado: LineaResultado, fase, nrodefase: Fase,
                 **kwargs):
        super(TabbedPanelItemResultados, self).__init__(**kwargs)
        self.text = f"Fase {nrodefase}"
        content = BoxLayout(padding=gridpadding)
        # content = BoxLayout(halign='left', valign="middle")
        content.orientation = 'vertical'
        content.add_widget(
            Label(text=f"{fase.nombre}", size_hint=(1.0, None), height=20))
        content.add_widget(
            Label(text="Captura de usuario:", size_hint=(1.0, None),
                  height=20))

        grid = GridLayout(
            cols=2,
            row_force_default=True,
            row_default_height=40,
            size_hint=(1.0, None),
            height=240,
            spacing=5,
            padding=gridpadding,
        )
        label = Label(text="Rostro", size_hint=(None, 1), width=100)
        with label.canvas.before:
            Color(firstrowcolor[0], firstrowcolor[1], firstrowcolor[2])
            label.rect = Rectangle(size=self.size, pos=self.pos)
        label.bind(pos=WidgetCreator.update_rect,
                   size=WidgetCreator.update_rect)
        grid.add_widget(label)

        rostro = BoxLayout(orientation='horizontal')
        rostro.add_widget(Label(text=resultado.captura.rostro.name))
        rostro.add_widget(
            Image(size_hint=(None, 0.9),
                  width=40,
                  source=SelectorDeIconos.iconoderostro(
                      resultado.captura.rostro)))
        with rostro.canvas.before:
            Color(firstrowcolor[0], firstrowcolor[1], firstrowcolor[2])
            rostro.rect = Rectangle(size=self.size, pos=self.pos)
        rostro.bind(pos=WidgetCreator.update_rect,
                    size=WidgetCreator.update_rect)
        grid.add_widget(rostro)

        label = Label(text="Mirada", size_hint=(None, 1), width=100)
        with label.canvas.before:
            Color(secondrowcolor[0], secondrowcolor[1], secondrowcolor[2])
            label.rect = Rectangle(size=self.size, pos=self.pos)
        label.bind(pos=WidgetCreator.update_rect,
                   size=WidgetCreator.update_rect)
        grid.add_widget(label)

        mirada = BoxLayout(orientation='horizontal')
        mirada.add_widget(Label(text=resultado.captura.mirada.name))
        mirada.add_widget(
            Image(size_hint=(None, 0.9),
                  width=40,
                  source=SelectorDeIconos.iconodemirada(
                      resultado.captura.mirada)))
        with mirada.canvas.before:
            Color(secondrowcolor[0], secondrowcolor[1], secondrowcolor[2])
            mirada.rect = Rectangle(size=self.size, pos=self.pos)
        mirada.bind(pos=WidgetCreator.update_rect,
                    size=WidgetCreator.update_rect)
        grid.add_widget(mirada)

        label = Label(text="Cabeza", size_hint=(None, 1), width=100)
        with label.canvas.before:
            Color(firstrowcolor[0], firstrowcolor[1], firstrowcolor[2])
            label.rect = Rectangle(size=self.size, pos=self.pos)
        label.bind(pos=WidgetCreator.update_rect,
                   size=WidgetCreator.update_rect)
        grid.add_widget(label)

        cabeza = BoxLayout(orientation='horizontal')
        cabeza.add_widget(Label(text=resultado.captura.cabeza.name))
        cabeza.add_widget(
            Image(size_hint=(None, 0.9),
                  width=40,
                  source=SelectorDeIconos.iconodecabeza(
                      resultado.captura.cabeza)))
        with cabeza.canvas.before:
            Color(firstrowcolor[0], firstrowcolor[1], firstrowcolor[2])
            cabeza.rect = Rectangle(size=self.size, pos=self.pos)
        cabeza.bind(pos=WidgetCreator.update_rect,
                    size=WidgetCreator.update_rect)
        grid.add_widget(cabeza)

        label = Label(text="Brazos", size_hint=(None, 1), width=100)
        with label.canvas.before:
            Color(secondrowcolor[0], secondrowcolor[1], secondrowcolor[2])
            label.rect = Rectangle(size=self.size, pos=self.pos)
        label.bind(pos=WidgetCreator.update_rect,
                   size=WidgetCreator.update_rect)
        grid.add_widget(label)

        brazos = BoxLayout(orientation='horizontal')
        brazos.add_widget(Label(text=resultado.captura.posicionbrazos.name))
        brazos.add_widget(
            Image(size_hint=(None, 0.9),
                  width=40,
                  source=SelectorDeIconos.iconodebrazos(
                      resultado.captura.posicionbrazos)))
        with brazos.canvas.before:
            Color(secondrowcolor[0], secondrowcolor[1], secondrowcolor[2])
            brazos.rect = Rectangle(size=self.size, pos=self.pos)
        brazos.bind(pos=WidgetCreator.update_rect,
                    size=WidgetCreator.update_rect)
        grid.add_widget(brazos)

        label = Label(text="Volumen de Voz", size_hint=(None, 1), width=100)
        with label.canvas.before:
            Color(firstrowcolor[0], firstrowcolor[1], firstrowcolor[2])
            label.rect = Rectangle(size=self.size, pos=self.pos)
        label.bind(pos=WidgetCreator.update_rect,
                   size=WidgetCreator.update_rect)
        grid.add_widget(label)

        volumen = BoxLayout(orientation='horizontal')
        volumen.add_widget(Label(text=str(resultado.captura.volumendevoz)))
        volumen.add_widget(
            Image(size_hint=(None, 0.9),
                  width=40,
                  source=SelectorDeIconos.iconodevolumen(
                      resultado.captura.volumendevoz)))
        with volumen.canvas.before:
            Color(firstrowcolor[0], firstrowcolor[1], firstrowcolor[2])
            volumen.rect = Rectangle(size=self.size, pos=self.pos)
        volumen.bind(pos=WidgetCreator.update_rect,
                     size=WidgetCreator.update_rect)
        grid.add_widget(volumen)

        label = Label(text="Palabras por minuto",
                      size_hint=(None, 1),
                      width=100)
        with label.canvas.before:
            Color(secondrowcolor[0], secondrowcolor[1], secondrowcolor[2])
            label.rect = Rectangle(size=self.size, pos=self.pos)
        label.bind(pos=WidgetCreator.update_rect,
                   size=WidgetCreator.update_rect)
        grid.add_widget(label)

        velocidad = BoxLayout(orientation='horizontal')
        velocidad.add_widget(
            Label(text=str(resultado.captura.palabrasporsegundo)))
        velocidad.add_widget(
            Image(size_hint=(None, 0.9),
                  width=40,
                  source=SelectorDeIconos.iconodevelocidad(
                      resultado.captura.palabrasporsegundo)))
        with velocidad.canvas.before:
            Color(secondrowcolor[0], secondrowcolor[1], secondrowcolor[2])
            velocidad.rect = Rectangle(size=self.size, pos=self.pos)
        velocidad.bind(pos=WidgetCreator.update_rect,
                       size=WidgetCreator.update_rect)
        grid.add_widget(velocidad)

        content.add_widget(grid)

        box = BoxLayout()
        box.add_widget(
            Label(text=f"Interpretación: {resultado.interpretacion.lectura}",
                  size_hint=(1.0, None),
                  height=20))
        content.add_widget(box)

        scrollableInfo = ScrollView(size_hint=(1.0, 1.0))
        scrollableInfo.add_widget(
            Label(text=f"{resultado.interpretacion.masinfo}"))
        content.add_widget(scrollableInfo)
        self.add_widget(content)