Skip to content

Instantly share code, notes, and snippets.

@m42e
Last active August 29, 2015 14:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m42e/12d4ad4c44dbcfb97f94 to your computer and use it in GitHub Desktop.
Save m42e/12d4ad4c44dbcfb97f94 to your computer and use it in GitHub Desktop.
File Sidebar For Pythonista
import keychaindb, ui, editor, os
class FileBarEntry (object):
def __init__(self, filename, open, delete):
self.filename = filename
self.open = open
self.delete = delete
class FileSidebar(object):
def __init__(self):
self.view = ui.View()
self.view.width=120
self.db = keychaindb.KeychainDB('openfile')
self.buttonheight = 30
self.files = []
self.update()
b_new = ui.Button(frame=(2,30,30,30), image=ui.Image.named('ionicons-plus-24'))
b_new.action = self.add
self.view.add_subview(b_new)
self.view.present('sidebar')
@ui.in_background
def add(self, sender):
if not editor.get_path() in self.db.values():
self.db[editor.get_path()] = editor.get_path()
self.update()
@ui.in_background
def openfile(self, sender):
file = next(x for x in self.files if x.open == sender)
editor.open_file(file.filename)
@ui.in_background
def deletefile(self, sender):
file = next(x for x in self.files if x.delete == sender)
del self.db[file.filename]
self.update()
@ui.in_background
def update(self):
for file in self.files:
self.view.remove_subview(file.open)
self.view.remove_subview(file.delete)
self.files = []
#Add subviews to main view and 'present' ui
offset = 50
for key,file in self.db.items():
#print os.path.basename(file)
filetitle = os.path.basename(file).replace('.py', '')
openf = ui.Button(frame=(2,offset,40,self.buttonheight), title=filetitle)
openf.width = 100
openf.content_mode = ui.CONTENT_SCALE_ASPECT_FIT
openf.action = self.openfile
self.view.add_subview(openf)
delfile = ui.Button(frame=(100,offset,20,self.buttonheight), image=ui.Image.named('ionicons-trash-a-24'))
delfile.action = self.deletefile
self.view.add_subview(delfile)
self.files.append(FileBarEntry(file, openf, delfile))
offset += self.buttonheight
self.view.set_needs_display()
if __name__=='__main__':
sidebar = FileSidebar()
#KeychainDB.py
#A script which enables the use of
#the Pythonista keychain as a persistent
#database. The database is accessed like a dict.
#Usage:
# from keychaindb import KeychainDB
# kdb = KeychainDB()
# kdb['key']
#Unfortunately the keychain can only hold
#strings, but it should be easy to type cast
import keychain
from UserDict import DictMixin
DB_NAME = 'KeychainDB'
class KeychainDB (DictMixin):
def __init__(self, appname, init=None):
self._keys = []
self._data = {}
self._dbname = DB_NAME+appname
if init is not None:
for key, value in init:
self[key] = value
def __setitem__(self, key, value):
keychain.set_password(self._dbname, key, value)
def __delitem__(self, key):
for service in keychain.get_services():
if key in service:
keychain.delete_password(self._dbname, key)
#No KeyError because user doesn't want the key there anyway
def __getitem__(self, key):
for service in keychain.get_services():
if key == service[1]:
return keychain.get_password(self._dbname, key)
raise KeyError
def keys(self):
return [s[1] for s in keychain.get_services() if s[0] == self._dbname]
def values(self):
return [keychain.get_password(self._dbname, k) for k in self.keys()]
@cclauss
Copy link

cclauss commented Feb 3, 2015

Subtle bug: It is not safe to use len(dict) to generate unique dict keys if the dict can shrink.

  • Add file 'A'.
  • Add file 'B'.
  • Del file 'A'.
  • Add file 'A'.

Result: File 'B' will be removed from the list because the last add overwrote it.
Instead, you could consider using key = str(hash(filename)).

Also, FileBarEntry could be replaced by:

import collections
FileBarEntry = collections.namedtuple('FileBarEntry', 'filename open delete')

Finally, add_file() does not appear to be used and could be commented out or deleted.

@m42e
Copy link
Author

m42e commented Feb 6, 2015

Thanks for your suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment