This repository has been archived on 2023-02-02. You can view files and clone it, but cannot push or open issues or pull requests.
barkshark-web/barkshark_web/component/status_bar.py
2022-04-16 06:23:04 -04:00

482 lines
13 KiB
Python

from .. import fediverse
from ..database import db, default_permissions
from ..exceptions import AccountNotFoundError, NoAccountsError
from ..functions import SignalBlock, connect, get_buffer_text
from ..objects.login_rows import SavedLoginRow
from ..passwords import passdb
class StatusBar:
def __init__(self, window):
self.window = window
self.app = window.app
self.siteoptions_handler_ids = []
self.bookmark_row = None
self.theme_enabled = False
self.toot_acct = None
self.toot_post = None
self.toot_max_len = 500
self.unsaved_logins = []
self.setup()
def bookmark_get_data(self):
data = DotDict()
for k,v in self.bookmark_fields.items():
if k == 'description':
data[k] = get_buffer_text(v.get_buffer())
else:
data[k] = v.get_text()
return data
def bookmark_set_data(self, name=None, url=None, category=None, description=None):
data = dict(name=name, url=url, category=category, description=description)
for k,v in data.items():
value = v if v != None else ''
if k == 'description':
self.bookmark_fields[k].get_buffer().set_text(value)
else:
self.bookmark_fields[k].set_text(value)
def login_unsaved_del_row(self, row):
self.logins.unsaved.remove(row['container'])
self.unsaved_logins.remove(row)
def login_unsaved_get_row(self, widget):
for row in self.unsaved_logins:
if widget == row['container']:
return row
def login_unsaved_new(self, data):
self.logins.unsaved.add(SavedLoginRow(data))
def login_unsaved_refresh(self):
for child in self.logins.unsaved.get_children():
self.logins.unsaved.remove(child)
child.destroy()
for row in self.unsaved_logins:
self.logins.unsaved(UnsavedLoginRow(row)['container'])
def toot_close(self, *args):
self.window['statusbar-toot-popover'].popdown()
def toot_clear(self, *args):
self.toot_fields.spoiler.set_text('')
self.toot_fields.content.get_buffer().set_text('')
self.toot_fields.visibility.set_active(0)
self.toot_update_count()
self.toot_set_reply()
def toot_set_account(self):
try:
self.toot_account = self.app.get_default_account()
except NoAccountsError:
self.window.notification('No active fedi accounts', 'error')
return False
return True
def toot_get_info(self):
return DotDict(
spoiler = self.toot_fields.spoiler.get_text(),
content = get_buffer_text(self.toot_fields.content.get_buffer()),
visibility = self.toot_fields.visibility.get_active_text()
)
def toot_send(self, *args):
data = self.toot_get_info()
options = {
'spoiler': data.spoiler,
'visibility': data.visibility.lower()
}
if not (data.spoiler or data.content):
return self.window.notification('Unwilling to send empty post', level='error')
if self.window['statusbar-toot-reply-scroll'].get_visible():
options['reply_id'] = self.toot_post.id
if fediverse.Post(self.toot_account.domain, self.toot_account.token, data.content, **options):
self.window.notification('Sent toot')
self.window['statusbar-toot-popover'].popdown()
self.toot_clear()
else:
self.window.notification('Failed to send toot', level='error')
def toot_set_reply(self, toot=None):
self.toot_post = toot
reply = self.toot_fields.reply
scroll = self.window['statusbar-toot-reply-scroll']
privacy = self.window['statusbar-toot-visibility']
account = self.toot_post.get('account') if toot else None
if not toot and not account:
scroll.hide()
return
text_buffer = reply.get_buffer()
text_buffer.set_text(f'Reply to: {account.display_name} ({account.acct}):\n\n{toot.content}')
reply.set_buffer(text_buffer)
privacy.set_active_id(toot.get('visibility', 'public'))
scroll.show()
def toot_update_count(self, *args):
spoiler = len(self.toot_fields.spoiler.get_text())
content = self.toot_fields.content.get_buffer().get_char_count()
num = spoiler + content
self.toot_fields.count.set_text(str(self.toot_max_len - num))
def handle_status_button(self, name):
try:
if not self.window[f'statusbar-{name}'].get_active():
return
except AttributeError:
pass
tab = self.window.active_tab
if name == 'debug':
#self.window.set_icons()
#self.window.themes.load_main()
#self.window.notification('Reloaded icons and main css', system=True)
#self.window.active_tab.editing_action('select')
#self.window.active_tab.editing_action('copy')
self.window.notification('Merp!', 'INFO', 0)
print(self.window.context.get_cookie_manager().delete_cookies_for_domain(self.window.active_tab.url.domain))
#if self.window.themes.current_theme:
#self.window.themes.UnloadTheme()
#else:
#self.window.themes.LoadTheme('test')
elif name == 'bookmark':
if not tab.url:
return
self.window['statusbar-bookmark-popover'].grab_focus()
with db.session as s:
self.bookmark_row = s.get_bookmark(tab.url)
if not self.bookmark_row:
self.window['statusbar-bookmark-delete'].set_sensitive(False)
return self.bookmark_set_data(
name = tab.title,
url = tab.url,
category = 'Default'
)
self.window['statusbar-bookmark-delete'].set_sensitive(True)
self.bookmark_set_data(
name = self.bookmark_row.name,
url = self.bookmark_row.url,
category = self.bookmark_row.category,
description = self.bookmark_row.description
)
elif name == 'siteoptions':
if not self.window['statusbar-siteoptions'].get_active() or not tab.url.hostname():
return
with db.session as s:
row = s.get_permission(tab.url.hostname())
self.window['statusbar-siteoptions-domain'].set_text(tab.url.hostname())
self.window['statusbar-siteoptions-reset'].set_sensitive(True if row != None else False)
self.siteoptions_row = row
with SignalBlock(self.siteoptions_handler_ids):
for k, v in default_permissions.items():
value = row.get(k, v)
self.window[f'statusbar-siteoptions-{k}'].set_state(value)
self.window['statusbar-siteoptions-reset'].set_sensitive(row and row.id != None)
self.window['statusbar-siteoptions-reset'].grab_focus()
elif name == 'logins':
self.window['statusbar-logins-saved-list'].grab_focus()
self.handle_logins_refresh()
elif name == 'toot':
if not self.toot_set_account():
return self.window['statusbar-toot-popover'].popdown()
self.toot_max_len = self.toot_account.toot_limit
self.toot_update_count()
self.toot_set_reply(self.toot_post)
self.window['statusbar-toot-content'].grab_focus()
def handle_bookmark_button(self, name):
with db.session as s:
if name == 'save':
data = self.bookmark_get_data()
if self.bookmark_row:
s.update_row(self.bookmark_row, **data)
else:
s.put_bookmark(**data)
elif name == 'delete':
if self.bookmark_row:
s.remove_row(self.bookmark_row)
self.window['statusbar-bookmark-popover'].popdown()
def handle_fedi_button(self, name):
post = self.window.active_tab.fedi_post
if not post or not self.toot_set_account():
return
domain, token = self.toot_account.domain, self.toot_account.token
if name == 'reply':
#self.toot_set_reply(post)
self.toot_post = post
self.window['statusbar-toot'].activate()
elif name == 'favorite':
if post.favourited == True:
if fediverse.UnFavorite(domain, token, post.id):
post.favourited = False
self.window.notification('Unfavorited post')
else:
self.window.notification('Failed to unfavorite post', 'error')
else:
if fediverse.Favorite(domain, token, post.id):
post.favourited = True
self.window.notification('Favorited post')
else:
self.window.notification('Failed to favorite post', 'error')
elif name == 'boost':
if post.reblogged == True:
if fediverse.UnBoost(domain, token, post.id):
post.reblogged = False
self.window.notification('Unboosted post')
else:
self.window.notification('Failed to unboost post', 'error')
else:
if fediverse.Boost(domain, token, post.id):
post.reblogged = True
self.window.notification('Boosted post')
else:
self.window.notification('Failed to boost post', 'error')
fediverse.cache.post.store(self.window.active_tab.url, post)
def handle_siteoptions_switch(self, name, switch):
tab = self.window.active_tab
if not tab.webview:
return
with db.session as s:
s.put_permission(tab.url.domain, name, switch.get_active())
self.window['statusbar-siteoptions-reset'].set_sensitive(True)
def handle_siteoptions_button(self, name):
if name == 'reset':
domain = self.window.active_tab.url.domain
with db.session as s:
s.del_permission(domain)
self.handle_status_button('siteoptions')
elif name == 'close':
self.window['statusbar-siteoptions-popover'].popdown()
def handle_logins_button(self, name):
if name == 'clear':
for widget in self.window['statusbar-logins-unsaved-list']:
widget.handle_cancel()
self.window['statusbar-logins-popover'].popdown()
def handle_logins_refresh(self):
login_list = self.window['statusbar-logins-saved-list']
for child in login_list.get_children():
child.destroy()
for row in passdb.fetch(domain=self.window.active_tab.url.hostname()):
login_list.add(SavedLoginRow(row, self.window.active_tab.url)['container'])
def handle_toot_key_press(self, textview, event, *args):
keyname = Gdk.keyval_name(event.keyval)
if keyname.lower() == 'return' and event.state == Gdk.ModifierType.CONTROL_MASK:
self.toot_send()
return True
def handle_toot_spoiler_activate(self, *args):
self.window['statusbar-toot-content'].grab_focus()
def setup(self):
self.bookmark_fields = DotDict(
name = self.window['statusbar-bookmark-title'],
url = self.window['statusbar-bookmark-url'],
category = self.window['statusbar-bookmark-category'],
description = self.window['statusbar-bookmark-description']
)
self.toot_fields = DotDict(
reply = self.window['statusbar-toot-reply'],
spoiler = self.window['statusbar-toot-spoiler'],
content = self.window['statusbar-toot-content'],
visibility = self.window['statusbar-toot-visibility'],
count = self.window['statusbar-toot-count']
)
self.logins = DotDict(
unsaved = self.window['statusbar-logins-unsaved-list'],
saved = self.window['statusbar-logins-saved-list']
)
signals = {
'bookmark': [
{'signal': 'toggled', 'callback': self.handle_status_button}
],
'bookmark-save': [
{'signal': 'clicked', 'callback': self.handle_bookmark_button}
],
'bookmark-delete': [
{'signal': 'clicked', 'callback': self.handle_bookmark_button}
],
'bookmark-close': [
{'signal': 'clicked', 'callback': self.handle_bookmark_button}
],
'favorite': [
{'signal': 'clicked', 'callback': self.handle_fedi_button}
],
'boost': [
{'signal': 'clicked', 'callback': self.handle_fedi_button}
],
'reply': [
{'signal': 'clicked', 'callback': self.handle_fedi_button}
],
'debug': [
{'signal': 'clicked', 'callback': self.handle_status_button}
],
'toot': [
{'signal': 'toggled', 'callback': self.handle_status_button}
],
'siteoptions': [
{'signal': 'toggled', 'callback': self.handle_status_button}
],
'logins': [
{'signal': 'toggled', 'callback': self.handle_status_button}
],
'logins-close': [
{'signal': 'clicked', 'callback': self.handle_logins_button}
],
'logins-unsaved-clear': [
{'signal': 'clicked', 'callback': self.handle_logins_button}
],
'siteoptions-reset': [
{'signal': 'clicked', 'callback': self.handle_siteoptions_button}
],
'siteoptions-close': [
{'signal': 'clicked', 'callback': self.handle_siteoptions_button}
],
'toot-spoiler': [
{'signal': 'changed', 'callback': self.toot_update_count},
{'signal': 'activate', 'callback': self.handle_toot_spoiler_activate}
],
'toot-reset': [
{'signal': 'clicked', 'callback': self.toot_clear}
],
'toot-send': [
{'signal': 'clicked', 'callback': self.toot_send}
],
'toot-close': [
{'signal': 'clicked', 'callback': self.toot_close}
],
'toot-content': [
{'signal': 'key-press-event', 'callback': self.handle_toot_key_press, 'kwargs': {'original_args': True}}
]
}
for name, sigs in signals.items():
for sig in sigs:
full_name = f'statusbar-{name}'
short_name = name.split('-')[-1]
self.window.Connect(full_name, sig['signal'], sig['callback'], short_name, *sig.get('args', []), **sig.get('kwargs', {}))
connect(self.window['statusbar-toot-content'].get_buffer(), 'changed', self.toot_update_count)
# extra work needs to be done to toggle webview settings
self.permissions = DotDict({
'instance': False,
'adblock': True,
'fullscreen': True,
'autoplay': False,
'dialog': True,
'notification': False,
'microphone': False,
'location': False,
'camera': False,
#'javascript': True,
#'images': True,
#'autoplay': False,
#'insecure': False
})
for name in self.permissions:
widget = self.window[f'statusbar-siteoptions-{name}']
sigid = self.window.Connect(f'statusbar-siteoptions-{name}', 'state-set', self.handle_siteoptions_switch, name, widget)
self.siteoptions_handler_ids.append([sigid, widget])