2022-11-08 17:53:59 -06:00
# -*- coding: utf-8 -*-
2022-11-11 15:51:16 -06:00
import os
2023-02-06 04:09:58 -06:00
import re
2022-11-11 15:51:16 -06:00
import wx
2022-11-08 17:53:59 -06:00
import widgetUtils
import config
2022-11-10 17:54:38 -06:00
import output
2023-02-06 04:09:58 -06:00
from twitter_text import parse_tweet , config
2023-04-03 13:35:05 -06:00
from controller import messages
2022-11-10 17:54:38 -06:00
from sessions . mastodon import templates
2022-11-16 13:28:45 -06:00
from wxUI . dialogs . mastodon import postDialogs
2022-11-08 17:53:59 -06:00
2023-02-06 04:09:58 -06:00
def character_count ( post_text , post_cw , character_limit = 500 ) :
# We will use text for counting character limit only.
full_text = post_text + post_cw
# find remote users as Mastodon doesn't count the domain in char limit.
users = re . findall ( " @[ \ w \ .-]+@[ \ w \ .-]+ " , full_text )
for user in users :
domain = user . split ( " @ " ) [ - 1 ]
full_text = full_text . replace ( " @ " + domain , " " )
options = config . config . get ( " defaults " )
options . update ( max_weighted_tweet_length = character_limit , default_weight = 100 )
parsed = parse_tweet ( full_text , options = options )
return parsed . weightedLength
2023-04-03 13:35:05 -06:00
class post ( messages . basicMessage ) :
2022-11-16 10:06:14 -06:00
def __init__ ( self , session , title , caption , text = " " , * args , * * kwargs ) :
# take max character limit from session as this might be different for some instances.
self . max = session . char_limit
2022-11-11 15:51:16 -06:00
self . title = title
self . session = session
2022-11-16 13:28:45 -06:00
self . message = postDialogs . Post ( caption = caption , text = text , * args , * * kwargs )
2022-11-11 15:51:16 -06:00
self . message . SetTitle ( title )
2022-11-08 17:53:59 -06:00
self . message . text . SetInsertionPoint ( len ( self . message . text . GetValue ( ) ) )
2022-11-11 15:51:16 -06:00
widgetUtils . connect_event ( self . message . spellcheck , widgetUtils . BUTTON_PRESSED , self . spellcheck )
widgetUtils . connect_event ( self . message . text , widgetUtils . ENTERED_TEXT , self . text_processor )
2023-02-06 04:09:58 -06:00
widgetUtils . connect_event ( self . message . spoiler , widgetUtils . ENTERED_TEXT , self . text_processor )
2022-11-11 15:51:16 -06:00
widgetUtils . connect_event ( self . message . translate , widgetUtils . BUTTON_PRESSED , self . translate )
widgetUtils . connect_event ( self . message . add , widgetUtils . BUTTON_PRESSED , self . on_attach )
widgetUtils . connect_event ( self . message . remove_attachment , widgetUtils . BUTTON_PRESSED , self . remove_attachment )
# ToDo: Add autocomplete feature to mastodon and uncomment this.
# widgetUtils.connect_event(self.message.autocomplete_users, widgetUtils.BUTTON_PRESSED, self.autocomplete_users)
2022-11-16 13:28:45 -06:00
widgetUtils . connect_event ( self . message . add_post , widgetUtils . BUTTON_PRESSED , self . add_post )
widgetUtils . connect_event ( self . message . remove_post , widgetUtils . BUTTON_PRESSED , self . remove_post )
2022-11-11 15:51:16 -06:00
self . attachments = [ ]
self . thread = [ ]
2022-11-08 17:53:59 -06:00
self . text_processor ( )
2022-11-16 13:28:45 -06:00
def add_post ( self , event , update_gui = True , * args , * * kwargs ) :
2022-11-11 15:51:16 -06:00
text = self . message . text . GetValue ( )
attachments = self . attachments [ : : ]
2022-11-16 13:28:45 -06:00
postdata = dict ( text = text , attachments = attachments , sensitive = self . message . sensitive . GetValue ( ) , spoiler_text = None )
if postdata . get ( " sensitive " ) == True :
postdata . update ( spoiler_text = self . message . spoiler . GetValue ( ) )
self . thread . append ( postdata )
2022-11-11 15:51:16 -06:00
self . attachments = [ ]
if update_gui :
self . message . reset_controls ( )
2022-11-16 13:28:45 -06:00
self . message . add_item ( item = [ text , len ( attachments ) ] , list_type = " post " )
2022-11-11 15:51:16 -06:00
self . message . text . SetFocus ( )
self . text_processor ( )
2022-11-16 13:28:45 -06:00
def get_post_data ( self ) :
self . add_post ( event = None , update_gui = False )
2022-11-11 15:51:16 -06:00
return self . thread
2023-03-23 13:17:55 -06:00
def set_post_data ( self , visibility , data ) :
2023-03-23 12:00:51 -06:00
if len ( data ) == 0 :
return
if len ( data ) > 1 :
self . thread = data [ : - 1 ]
for p in self . thread :
2023-03-23 13:17:55 -06:00
self . message . add_item ( item = [ p . get ( " text " ) or " " , len ( p . get ( " attachments " ) or [ ] ) ] , list_type = " post " )
2023-03-23 12:00:51 -06:00
post = data [ - 1 ]
2023-03-23 13:17:55 -06:00
self . attachments = post . get ( " attachments " ) or [ ]
self . message . text . SetValue ( post . get ( " text " ) or " " )
self . message . sensitive . SetValue ( post . get ( " sensitive " ) or False )
self . message . spoiler . SetValue ( post . get ( " spoiler_text " ) or " " )
visibility_settings = dict ( public = 0 , unlisted = 1 , private = 2 , direct = 3 )
self . message . visibility . SetSelection ( visibility_settings . get ( visibility ) )
self . message . on_sensitivity_changed ( )
self . text_processor ( )
2023-03-23 12:00:51 -06:00
2022-11-08 17:53:59 -06:00
def text_processor ( self , * args , * * kwargs ) :
2023-02-06 04:09:58 -06:00
text = self . message . text . GetValue ( )
cw = self . message . spoiler . GetValue ( )
results = character_count ( text , cw , character_limit = self . max )
self . message . SetTitle ( _ ( " %s - %s of %d characters " ) % ( self . title , results , self . max ) )
if results > self . max :
self . session . sound . play ( " max_length.ogg " )
2022-11-11 15:51:16 -06:00
if len ( self . thread ) > 0 :
2022-11-16 13:28:45 -06:00
if hasattr ( self . message , " posts " ) :
self . message . posts . Enable ( True )
self . message . remove_post . Enable ( True )
2022-11-11 15:51:16 -06:00
else :
2022-11-16 13:28:45 -06:00
self . message . posts . Enable ( False )
self . message . remove_post . Enable ( False )
2022-11-08 17:53:59 -06:00
if len ( self . attachments ) > 0 :
self . message . attachments . Enable ( True )
self . message . remove_attachment . Enable ( True )
else :
self . message . attachments . Enable ( False )
self . message . remove_attachment . Enable ( False )
2022-11-11 15:51:16 -06:00
if len ( self . message . text . GetValue ( ) ) > 0 or len ( self . attachments ) > 0 :
2022-11-16 13:28:45 -06:00
self . message . add_post . Enable ( True )
2022-11-08 17:53:59 -06:00
else :
2022-11-16 13:28:45 -06:00
self . message . add_post . Enable ( False )
2022-11-11 15:51:16 -06:00
2022-11-16 13:28:45 -06:00
def remove_post ( self , * args , * * kwargs ) :
post = self . message . posts . GetFocusedItem ( )
if post > - 1 and len ( self . thread ) > post :
self . thread . pop ( post )
self . message . remove_item ( list_type = " post " )
2022-11-11 15:51:16 -06:00
self . text_processor ( )
self . message . text . SetFocus ( )
def can_attach ( self ) :
if len ( self . attachments ) == 0 :
return True
elif len ( self . attachments ) == 1 and ( self . attachments [ 0 ] [ " type " ] == " poll " or self . attachments [ 0 ] [ " type " ] == " video " or self . attachments [ 0 ] [ " type " ] == " audio " ) :
return False
elif len ( self . attachments ) < 4 :
return True
return False
def on_attach ( self , * args , * * kwargs ) :
can_attach = self . can_attach ( )
menu = self . message . attach_menu ( can_attach )
self . message . Bind ( wx . EVT_MENU , self . on_attach_image , self . message . add_image )
self . message . Bind ( wx . EVT_MENU , self . on_attach_video , self . message . add_video )
self . message . Bind ( wx . EVT_MENU , self . on_attach_audio , self . message . add_audio )
self . message . Bind ( wx . EVT_MENU , self . on_attach_poll , self . message . add_poll )
self . message . PopupMenu ( menu , self . message . add . GetPosition ( ) )
def on_attach_image ( self , * args , * * kwargs ) :
can_attach = self . can_attach ( )
big_media_present = False
for a in self . attachments :
if a [ " type " ] == " video " or a [ " type " ] == " audio " or a [ " type " ] == " poll " :
big_media_present = True
break
if can_attach == False or big_media_present == True :
return self . message . unable_to_attach_file ( )
image , description = self . message . get_image ( )
if image != None :
if image . endswith ( " gif " ) :
image_type = " gif "
else :
image_type = " photo "
imageInfo = { " type " : image_type , " file " : image , " description " : description }
if len ( self . attachments ) > 0 and image_type == " gif " :
return self . message . unable_to_attach_file ( )
self . attachments . append ( imageInfo )
self . message . add_item ( item = [ os . path . basename ( imageInfo [ " file " ] ) , imageInfo [ " type " ] , imageInfo [ " description " ] ] )
self . text_processor ( )
def on_attach_video ( self , * args , * * kwargs ) :
if len ( self . attachments ) > = 4 :
return self . message . unable_to_attach_file ( )
can_attach = self . can_attach ( )
big_media_present = False
for a in self . attachments :
if a [ " type " ] == " video " or a [ " type " ] == " audio " or a [ " type " ] == " poll " :
big_media_present = True
break
if can_attach == False or big_media_present == True :
return self . message . unable_to_attach_file ( )
2023-02-10 01:01:25 -06:00
video , description = self . message . get_video ( )
2022-11-11 15:51:16 -06:00
if video != None :
2023-02-10 01:01:25 -06:00
videoInfo = { " type " : " video " , " file " : video , " description " : description }
2022-11-11 15:51:16 -06:00
self . attachments . append ( videoInfo )
self . message . add_item ( item = [ os . path . basename ( videoInfo [ " file " ] ) , videoInfo [ " type " ] , videoInfo [ " description " ] ] )
self . text_processor ( )
def on_attach_audio ( self , * args , * * kwargs ) :
if len ( self . attachments ) > = 4 :
return self . message . unable_to_attach_file ( )
can_attach = self . can_attach ( )
big_media_present = False
for a in self . attachments :
if a [ " type " ] == " video " or a [ " type " ] == " audio " or a [ " type " ] == " poll " :
big_media_present = True
break
if can_attach == False or big_media_present == True :
return self . message . unable_to_attach_file ( )
2023-02-10 01:01:25 -06:00
audio , description = self . message . get_audio ( )
2022-11-11 15:51:16 -06:00
if audio != None :
2023-02-10 01:01:25 -06:00
audioInfo = { " type " : " audio " , " file " : audio , " description " : description }
2022-11-11 15:51:16 -06:00
self . attachments . append ( audioInfo )
self . message . add_item ( item = [ os . path . basename ( audioInfo [ " file " ] ) , audioInfo [ " type " ] , audioInfo [ " description " ] ] )
self . text_processor ( )
def on_attach_poll ( self , * args , * * kwargs ) :
if len ( self . attachments ) > 0 :
return self . message . unable_to_attach_poll ( )
can_attach = self . can_attach ( )
big_media_present = False
for a in self . attachments :
if a [ " type " ] == " video " or a [ " type " ] == " audio " or a [ " type " ] == " poll " :
big_media_present = True
break
if can_attach == False or big_media_present == True :
return self . message . unable_to_attach_file ( )
2022-11-16 13:28:45 -06:00
dlg = postDialogs . poll ( )
2022-11-11 15:51:16 -06:00
if dlg . ShowModal ( ) == wx . ID_OK :
day = 86400
periods = [ 300 , 1800 , 3600 , 21600 , day , day * 2 , day * 3 , day * 4 , day * 5 , day * 6 , day * 7 ]
period = periods [ dlg . period . GetSelection ( ) ]
poll_options = dlg . get_options ( )
multiple = dlg . multiple . GetValue ( )
hide_totals = dlg . hide_votes . GetValue ( )
data = dict ( type = " poll " , file = " " , description = _ ( " Poll with {} options " ) . format ( len ( poll_options ) ) , options = poll_options , expires_in = period , multiple = multiple , hide_totals = hide_totals )
self . attachments . append ( data )
self . message . add_item ( item = [ data [ " file " ] , data [ " type " ] , data [ " description " ] ] )
self . text_processor ( )
dlg . Destroy ( )
def get_data ( self ) :
2022-11-16 13:28:45 -06:00
self . add_post ( event = None , update_gui = False )
2022-11-11 15:51:16 -06:00
return self . thread
2022-11-08 17:53:59 -06:00
2022-11-11 15:51:16 -06:00
def get_visibility ( self ) :
visibility_settings = [ " public " , " unlisted " , " private " , " direct " ]
return visibility_settings [ self . message . visibility . GetSelection ( ) ]
2022-11-10 17:54:38 -06:00
2022-12-23 13:58:10 -06:00
def set_visibility ( self , setting ) :
visibility_settings = [ " public " , " unlisted " , " private " , " direct " ]
visibility_setting = visibility_settings . index ( setting )
self . message . visibility . SetSelection ( setting )
2022-11-16 13:28:45 -06:00
class viewPost ( post ) :
def __init__ ( self , post , offset_hours = 0 , date = " " , item_url = " " ) :
if post . reblog != None :
post = post . reblog
author = post . account . display_name if post . account . display_name != " " else post . account . username
title = _ ( u " Post from {} " ) . format ( author )
image_description = templates . process_image_descriptions ( post . media_attachments )
text = templates . process_text ( post , safe = False )
date = templates . process_date ( post . created_at , relative_times = False , offset_hours = offset_hours )
2022-11-12 15:16:53 -06:00
privacy_settings = dict ( public = _ ( " Public " ) , unlisted = _ ( " Not listed " ) , private = _ ( " followers only " ) , direct = _ ( " Direct " ) )
2022-11-16 13:28:45 -06:00
privacy = privacy_settings . get ( post . visibility )
boost_count = str ( post . reblogs_count )
favs_count = str ( post . favourites_count )
# Gets the client from where this post was made.
source_obj = post . get ( " application " )
2022-11-10 17:54:38 -06:00
if source_obj == None :
source = _ ( " Remote instance " )
else :
source = source_obj . get ( " name " )
2022-11-16 13:28:45 -06:00
self . message = postDialogs . viewPost ( text = text , boosts_count = boost_count , favs_count = favs_count , source = source , date = date , privacy = privacy )
2022-11-10 17:54:38 -06:00
self . message . SetTitle ( title )
if image_description != " " :
self . message . image_description . Enable ( True )
self . message . image_description . ChangeValue ( image_description )
widgetUtils . connect_event ( self . message . spellcheck , widgetUtils . BUTTON_PRESSED , self . spellcheck )
if item_url != " " :
self . message . enable_button ( " share " )
widgetUtils . connect_event ( self . message . share , widgetUtils . BUTTON_PRESSED , self . share )
self . item_url = item_url
widgetUtils . connect_event ( self . message . translateButton , widgetUtils . BUTTON_PRESSED , self . translate )
self . message . ShowModal ( )
# We won't need text_processor in this dialog, so let's avoid it.
def text_processor ( self ) :
pass
def share ( self , * args , * * kwargs ) :
if hasattr ( self , " item_url " ) :
output . copy ( self . item_url )
output . speak ( _ ( " Link copied to clipboard. " ) )