def send_data(text, full_info, subject="", network_send=True): ''' Sends the data to our servers through a post request ''' files = {} # packs all the information into 'files' if full_info: files['report'] = get_metadata_archive() # This is the actual info: subject, text, email, username payload = { "text": text, "email": get_email(), "username": get_mixed_username(), "category": "os", "subject": subject } if not network_send: return True, None # send the bug report and remove all the created files success, error, data = request_wrapper('post', '/feedback', data=payload, files=files) delete_tmp_dir() if not success: return False, error if full_info: # kano-profile stat collection increment_app_state_variable_with_dialog('kano-feedback', 'bugs_submitted', 1) # logs were sent, clean up logging.cleanup() return True, None
def share(filename): # TODO: Move this connection handling into a function in Kano Utils import subprocess if not is_internet(): subprocess.call(['sudo', 'kano-settings', '4']) if not is_internet(): return 'You have no internet' success, _ = login_using_token() if not success: os.system('kano-login 3') success, _ = login_using_token() if not success: return 'Cannot login' data = json.loads(request.data) filename, filepath = _save(data) success, msg = upload_share(filepath, filename, APP_NAME) if not success: return msg increment_app_state_variable_with_dialog(APP_NAME, 'shared', 1) return ''
def _increment_lines_of_code(): data = json.loads(request.data) new_lines = data["newLines"] increment_app_state_variable_with_dialog(APP_NAME, "lines_of_code", new_lines) return ""
def launch_boot_gui(): # FIXME: This window uses Gtk2 which requires the other Gtk imports to be # loaded in the scope of the functions that require them. old_status = clean(dry_run=True) status = UpdaterStatus.get_instance() if old_status == UpdaterStatus.INSTALLING_UPDATES: status.notifications_muted = True status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() remove_pid_file() cmd_args = ['kano-updater', 'install', '--gui', '--no-confirm'] os.execvp('kano-updater', cmd_args) elif old_status == UpdaterStatus.UPDATES_INSTALLED: try: from kano_profile.badges import \ increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog( 'kano-updater', 'updated', 1) except Exception: pass from kano_updater.ui.changes_dialog import ChangesDialog win = ChangesDialog() win.run() status.save()
def _increment_lines_of_code(): data = json.loads(request.data) new_lines = data['newLines'] increment_app_state_variable_with_dialog(APP_NAME, 'lines_of_code', new_lines) return ''
def send_data(text, full_info, subject='', network_send=True, logs_path=''): """Sends the data to our servers through a post request. It uses :func:`~get_metadata_archive` to gather all the logs on the system. Args: text (str): The description of the email when sending the logs full_info (bool): Whether to attach all logs to the payload subject (str): The title of the email when sending the logs network_send (bool): Whether to send the data to our servers logs_path (str): Path to an existing logs archive to use instead Returns: bool, error: Whether the operation was successful or there was an error as returned by :func:`kano_world.functions.request_wrapper` """ from kano_world.functions import get_email, get_mixed_username files = {} # packs all the information into 'files' if full_info: if logs_path and os.path.exists(logs_path): files['report'] = open(logs_path, 'rb') else: files['report'] = get_metadata_archive(title=subject, desc=text) # This is the actual info: subject, text, email, username payload = { "text": text, "email": get_email(), "username": get_mixed_username(), "category": "os", "subject": subject } if not network_send: return True, None # send the bug report and remove all the created files success, error, data = request_wrapper('post', '/feedback', data=payload, files=files) delete_tmp_dir() if not success: return False, error if full_info: # kano-profile stat collection from kano_profile.badges import increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog('kano-feedback', 'bugs_submitted', 1) # logs were sent, clean up logging.cleanup() return True, None
def share_theme(): # Check for internet if not is_internet(): coloured_error, junk1, junk2 = run_cmd( 'colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + _( 'You need internet connection') exit(2) # Check for login success, junk2 = login_using_token() if not success: coloured_error, junk1, junk2 = run_cmd( 'colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + _( 'You need to login to Kano World') exit(2) # Print themes print_themes(False, False) # Select theme dialogue message = _(" 1) Select a theme: ") theme = raw_input(message) theme += '.xml' # Check theme exists check_valid_theme(theme) # Select title message = _(" 2) Write a title: ") title = raw_input(message) if title: # The API limits title to 200 characters (cut it here) title = title[:200] else: title = 'My snake' # Select description message = _(" 3) Write a description: ") description = raw_input(message) if description: # The API limits description to 500 characters (cut it here) description = description[:500] # Create json create_share_json(theme, title, description) # Share filepath = os.path.join(app_dir, theme) success, msg = upload_share(filepath, title, 'make-snake') if not success: coloured_error, junk1, junk2 = run_cmd( 'colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip( '\n') + _('Sharing of {} failed. {}\n') % (theme, msg) exit(2) message, junk1, junk2 = run_cmd( 'colour_echo "{{4 + }} {{3 You have shared your theme successfully }}"' ) print "\n " + message.strip('\n') increment_app_state_variable_with_dialog('make-snake', 'shared', 1) exit(2)
def share_theme(): # Check for internet if not is_internet(): coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip( '\n') + 'You need internet connection' exit(2) # Check for login success, _ = login_using_token() if not success: coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip( '\n') + 'You need to login to Kano World' exit(2) # Print themes print_themes(False, False) # Select theme dialogue message = " 1) Select a theme: " theme = raw_input(message) theme += '.xml' # Check theme exists check_valid_theme(theme) # Select title message = " 2) Write a title: " title = raw_input(message) if not title: title = 'My snake' # Select description message = " 3) Write a description: " description = raw_input(message) # Create json create_share_json(theme, title, description) # Share filepath = os.path.join(app_dir, theme) success, msg = upload_share(filepath, title, 'make-snake') if not success: coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip( '\n') + 'Sharing of %s failed. %s\n' % (theme, msg) exit(2) message, _, _ = run_cmd( 'colour_echo "{{4 + }} {{3 You have shared your theme successfully }}"' ) print "\n " + message.strip('\n') increment_app_state_variable_with_dialog('make-snake', 'shared', 1) exit(2)
def launch_boot_gui(): # FIXME: This window uses Gtk2 which requires the other Gtk imports to be # loaded in the scope of the functions that require them. old_status = clean(dry_run=True) status = UpdaterStatus.get_instance() if old_status == UpdaterStatus.INSTALLING_UPDATES: from kano.gtk3.kano_dialog import KanoDialog d = KanoDialog( 'Continue updating', 'The update you started didn\'t finish. Would you like to ' 'continue?', [{"label": "YES", "return_value": True, "color": "green"}], orange_info={'name': 'SKIP', 'return_value': False}, ) rv = d.run() del d if rv: status.notifications_muted = True status.state = UpdaterStatus.NO_UPDATES status.save() remove_pid_file() cmd_args = ['kano-updater', 'install', '--gui', '--no-confirm'] os.execvp('kano-updater', cmd_args) elif old_status == UpdaterStatus.UPDATES_INSTALLED: try: from kano_profile.badges import \ increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog( 'kano-updater', 'updated', 1) except Exception: pass from kano_updater.ui.changes_dialog import ChangesDialog win = ChangesDialog() win.run() status.save()
def share(filename): # TODO: Move this connection handling into a function in Kano Utils import subprocess if not is_internet(): subprocess.call(["sudo", "kano-settings", "4"]) if not is_internet(): return "You have no internet" data = json.loads(request.data) filename, filepath = _save(data) success, msg = login_and_share(filepath, filename, APP_NAME) if not success: return msg increment_app_state_variable_with_dialog(APP_NAME, "shared", 1) return ""
def share_theme(): # Check for internet if not is_internet(): coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + 'You need internet connection' exit(2) # Check for login success, _ = login_using_token() if not success: coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + 'You need to login to Kano World' exit(2) # Print themes print_themes(False, False) # Select theme dialogue message = " 1) Select a theme: " theme = raw_input(message) theme += '.xml' # Check theme exists check_valid_theme(theme) # Select title message = " 2) Write a title: " title = raw_input(message) if not title: title = 'My snake' # Select description message = " 3) Write a description: " description = raw_input(message) # Create json create_share_json(theme, title, description) # Share filepath = os.path.join(app_dir, theme) success, msg = upload_share(filepath, title, 'make-snake') if not success: coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + 'Sharing of %s failed. %s\n' % (theme, msg) exit(2) message, _, _ = run_cmd('colour_echo "{{4 + }} {{3 You have shared your theme successfully }}"') print "\n " + message.strip('\n') increment_app_state_variable_with_dialog('make-snake', 'shared', 1) exit(2)
def update_profile_stats(): update_upwards_with_dialog('make-snake', 'longest_snake', STATUS['longest_snake']) update_upwards_with_dialog('make-snake', 'highest_score', STATUS['highest_score']) increment_app_state_variable_with_dialog('make-snake', 'total_length', STATUS['total_length']) increment_app_state_variable_with_dialog('make-snake', 'total_number_of_apples', STATUS['total_number_of_apples']) increment_app_state_variable_with_dialog('make-snake', 'total_score', STATUS['total_score'])
def update_profile_stats(): update_upwards_with_dialog( 'make-snake', 'longest_snake', STATUS['longest_snake'] ) update_upwards_with_dialog( 'make-snake', 'highest_score', STATUS['highest_score'] ) increment_app_state_variable_with_dialog( 'make-snake', 'total_length', STATUS['total_length'] ) increment_app_state_variable_with_dialog( 'make-snake', 'total_number_of_apples', STATUS['total_number_of_apples'] ) increment_app_state_variable_with_dialog( 'make-snake', 'total_score', STATUS['total_score'] )
def report_window(self): ''' Report window Contains 2 text views and Take Screenshot, Add Image and Send buttons ''' ApplicationWindow.__init__(self, _('Report a Problem'), self.WIDTH, 0.35) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) self.set_icon_name("feedback") self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar(title=_("Report a Problem"), window_width=self.WIDTH, has_buttons=False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) self.entry = Gtk.Entry() self.entry.props.placeholder_text = _("Add subject (optional)") self.entry.set_margin_left(20) self.entry.set_margin_right(20) self.entry.set_margin_top(20) self.entry.set_margin_bottom(10) self._grid.attach(self.entry, 0, 0, 1, 1) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._textbuffer = self._text.get_buffer() self._textbuffer.set_text(_("Type your problem here!")) self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 1, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create take screenshot button self._screenshot_button = KanoButton(_("TAKE SCREENSHOT"), "blue") self._screenshot_button.set_sensitive(True) self._screenshot_button.connect("button_press_event", self.screenshot_clicked) # Create attach screenshot button self._attach_button = KanoButton(_("ADD IMAGE"), "blue") self._attach_button.set_sensitive(True) self._attach_button.connect("button_press_event", self.attach_clicked) # Create send button self._send_button = KanoButton(_("SEND")) self._send_button.set_sensitive(False) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.set_margin(10, 0, 10, 0) self.screenshot_box = Gtk.ButtonBox() self.screenshot_box.set_layout(Gtk.ButtonBoxStyle.CENTER) self.screenshot_box.set_spacing(20) self.pack_screenshot_buttons() self.screenshot_box.set_margin_bottom(20) self._grid.attach(self.screenshot_box, 0, 2, 1, 1) # Create grey box to put the button in self.bottom_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.bottom_box.pack_start(self._send_button.align, False, False, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self.bottom_box) self._grid.attach(bottom_background, 0, 3, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog('kano-feedback', 'starts', 1) except Exception: pass
def contact_window(self): ''' Contact Us window Contains text view and a Send button ''' # delete the directory containing all the info we'll send, and recreate delete_tmp_dir() create_tmp_dir() ApplicationWindow.__init__(self, 'Contact Us', self.WIDTH, 0.35) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # Make sure this window has no icon in the task bar # so it plays nice with kdesk-blur self.set_property('skip-taskbar-hint', True) self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar(title="Contact Us", window_width=self.WIDTH, has_buttons=False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._textbuffer = self._text.get_buffer() self._textbuffer.set_text("Type your feedback here!") self._clear_buffer_handler_id = self._textbuffer.connect("insert-text", self.clear_buffer) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 0, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create send button self._send_button = KanoButton("SEND") self._send_button.set_sensitive(False) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.align.set_padding(10, 10, 0, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self._send_button.align) self._grid.attach(bottom_background, 0, 1, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog('kano-feedback', 'starts', 1) except Exception: pass
def report_window(self): ''' Report window Contains 2 text views and Take Screenshot, Add Image and Send buttons ''' ApplicationWindow.__init__(self, 'Report a Problem', self.WIDTH, 0.35) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) self.set_icon_name("feedback") self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar(title="Report a Problem", window_width=self.WIDTH, has_buttons=False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) self.entry = Gtk.Entry() self.entry.props.placeholder_text = "Add subject (optional)" self.entry.set_margin_left(20) self.entry.set_margin_right(20) self.entry.set_margin_top(20) self.entry.set_margin_bottom(10) self._grid.attach(self.entry, 0, 0, 1, 1) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._textbuffer = self._text.get_buffer() self._textbuffer.set_text("Type your problem here!") self._clear_buffer_handler_id = self._textbuffer.connect("insert-text", self.clear_buffer) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 1, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create take screenshot button self._screenshot_button = KanoButton("TAKE SCREENSHOT", "blue") self._screenshot_button.set_sensitive(True) self._screenshot_button.connect("button_press_event", self.screenshot_clicked) # Create attach screenshot button self._attach_button = KanoButton("ADD IMAGE", "blue") self._attach_button.set_sensitive(True) self._attach_button.connect("button_press_event", self.attach_clicked) # Create send button self._send_button = KanoButton("SEND") self._send_button.set_sensitive(False) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.set_margin(10, 0, 10, 0) self.screenshot_box = Gtk.ButtonBox() self.screenshot_box.set_layout(Gtk.ButtonBoxStyle.CENTER) self.screenshot_box.set_spacing(20) self.pack_screenshot_buttons() self.screenshot_box.set_margin_bottom(20) self._grid.attach(self.screenshot_box, 0, 2, 1, 1) # Create grey box to put the button in self.bottom_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.bottom_box.pack_start(self._send_button.align, False, False, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self.bottom_box) self._grid.attach(bottom_background, 0, 3, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog('kano-feedback', 'starts', 1) except Exception: pass
def contact_window(self): ''' Contact Us window Contains text view and a Send button ''' # delete the directory containing all the info we'll send, and recreate delete_tmp_dir() create_tmp_dir() ApplicationWindow.__init__(self, _('Contact Us'), self.WIDTH, 0.35) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # Make sure this window has no icon in the task bar # so it plays nice with kdesk-blur self.set_property('skip-taskbar-hint', True) self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar(title=_("Contact Us"), window_width=self.WIDTH, has_buttons=False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._textbuffer = self._text.get_buffer() self._textbuffer.set_text(_("Type your feedback here!")) self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 0, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create send button self._send_button = KanoButton(_("SEND")) self._send_button.set_sensitive(False) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.align.set_padding(10, 10, 0, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self._send_button.align) self._grid.attach(bottom_background, 0, 1, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog('kano-feedback', 'starts', 1) except Exception: pass