| 1 | # Copyright (C) 2011 Walter Bender |
| 2 | # |
| 3 | # This program is free software; you can redistribute it and/or modify |
| 4 | # it under the terms of the GNU General Public License as published by |
| 5 | # the Free Software Foundation; either version 2 of the License, or |
| 6 | # (at your option) any later version. |
| 7 | # |
| 8 | # This program is distributed in the hope that it will be useful, |
| 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | # GNU General Public License for more details. |
| 12 | # |
| 13 | # You should have received a copy of the GNU General Public License |
| 14 | # along with this program; if not, write to the Free Software |
| 15 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 16 | |
| 17 | import os |
| 18 | import subprocess |
| 19 | import gtk |
| 20 | |
| 21 | import logging |
| 22 | _logger = logging.getLogger('ViewSource') |
| 23 | |
| 24 | CUSTOMICON = 'customize.svg' |
| 25 | RESCALE = ' <g transform="matrix(0.73,0,0,0.73,7.57,7.96)">\n' |
| 26 | |
| 27 | |
| 28 | def customize_bundle(home_activities, new_bundle_name): |
| 29 | ''' Modify bundle_id in new activity.info file. ''' |
| 30 | fd_old = open(os.path.join(home_activities, new_bundle_name, |
| 31 | 'activity', 'activity.info'), 'r') |
| 32 | fd_new = open(os.path.join(home_activities, new_bundle_name, |
| 33 | 'activity', 'new_activity.info'), 'w') |
| 34 | for line in fd_old: |
| 35 | tokens = line.split('=') |
| 36 | if tokens[0].rstrip() == 'bundle_id': |
| 37 | new_bundle_id = tokens[1].strip() + '_my_copy' |
| 38 | fd_new.write('%s = %s\n' % (tokens[0].rstrip(), new_bundle_id)) |
| 39 | elif tokens[0].rstrip() == 'icon': |
| 40 | old_icon_name = tokens[1].strip() |
| 41 | new_icon_name = 'My' + old_icon_name |
| 42 | fd_new.write('%s = %s\n' % (tokens[0].rstrip(), new_icon_name)) |
| 43 | else: |
| 44 | fd_new.write(line) |
| 45 | fd_old.close |
| 46 | fd_new.close |
| 47 | command_line = ['mv', os.path.join(home_activities, new_bundle_name, |
| 48 | 'activity', 'new_activity.info'), |
| 49 | os.path.join(home_activities, new_bundle_name, |
| 50 | 'activity', 'activity.info')] |
| 51 | _logger.debug(subprocess.call(command_line)) |
| 52 | |
| 53 | _custom_icon(home_activities, new_bundle_name, old_icon_name, |
| 54 | new_icon_name) |
| 55 | |
| 56 | |
| 57 | def _custom_icon(home_activities, new_bundle_name, old_icon_name, |
| 58 | new_icon_name): |
| 59 | ''' Modify new activity icon by overlaying custom icon. ''' |
| 60 | |
| 61 | # First, find customize.svg, which will be used as an overlay. |
| 62 | for path in gtk.icon_theme_get_default().get_search_path(): |
| 63 | if os.path.exists(os.path.join(path, 'sugar', 'scalable', 'actions', |
| 64 | CUSTOMICON)): |
| 65 | break |
| 66 | else: |
| 67 | path = None |
| 68 | |
| 69 | if path == None: |
| 70 | _logger.debug('customize.svg not found') |
| 71 | command_line = ['mv', os.path.join(home_activities, new_bundle_name, |
| 72 | 'activity', old_icon_name + '.svg'), |
| 73 | os.path.join(home_activities, new_bundle_name, |
| 74 | 'activity', new_icon_name + '.svg')] |
| 75 | _logger.debug(subprocess.call(command_line)) |
| 76 | return |
| 77 | |
| 78 | # Extract custom_svg, i.e., the 'payload' from the svg file. |
| 79 | fd_custom = open(os.path.join(path, 'sugar', 'scalable', 'actions', |
| 80 | CUSTOMICON), 'r') |
| 81 | |
| 82 | custom_svg = '' |
| 83 | found_begin_svg_tag = False |
| 84 | found_close_tag = False |
| 85 | found_end_svg_tag = False |
| 86 | |
| 87 | for line in fd_custom: |
| 88 | if not found_begin_svg_tag: |
| 89 | if line.count('<svg') > 0: |
| 90 | found_begin_svg_tag = True |
| 91 | partials = line.split('<svg') |
| 92 | found_close_tag, temp_string = _find_and_split( |
| 93 | partials[1], '>', '', None) |
| 94 | else: |
| 95 | pass |
| 96 | elif not found_close_tag: |
| 97 | found_close_tag, temp_string = _find_and_split( |
| 98 | line, '>', '', None) |
| 99 | temp_string = '' |
| 100 | elif not found_end_svg_tag: |
| 101 | custom_svg += temp_string |
| 102 | found_end_svg_tag, temp_string = _find_and_split( |
| 103 | line, '</svg>', '', None) |
| 104 | else: |
| 105 | custom += line |
| 106 | fd_custom.close |
| 107 | |
| 108 | # Next, modify the old icon by shrinking it and applying the overlay. |
| 109 | fd_old = open(os.path.join(home_activities, new_bundle_name, 'activity', |
| 110 | old_icon_name + '.svg'), 'r') |
| 111 | fd_new = open(os.path.join(home_activities, new_bundle_name, 'activity', |
| 112 | new_icon_name + '.svg'), 'w') |
| 113 | |
| 114 | found_begin_svg_tag = False |
| 115 | found_close_tag = False |
| 116 | found_end_svg_tag = False |
| 117 | |
| 118 | for line in fd_old: |
| 119 | if not found_begin_svg_tag: |
| 120 | if line.count('<svg') > 0: |
| 121 | found_begin_svg_tag = True |
| 122 | partials = line.split('<svg') |
| 123 | fd_new.write(partials[0] + '<svg\n') |
| 124 | found_close_tag = _find_and_split(partials[1], '>', |
| 125 | RESCALE, fd_new) |
| 126 | else: |
| 127 | fd_new.write(line) |
| 128 | elif not found_close_tag: |
| 129 | found_close_tag = _find_and_split(line, '>', RESCALE, fd_new) |
| 130 | elif not found_end_svg_tag: |
| 131 | found_end_svg_tag = _find_and_split( |
| 132 | line, '</svg>', ' </g>\n' + custom_svg, fd_new, |
| 133 | insert_before=True) |
| 134 | else: |
| 135 | fd_new.write(line) |
| 136 | fd_old.close |
| 137 | fd_new.close |
| 138 | |
| 139 | |
| 140 | def _find_and_split(line, token, insert, fd, insert_before=False): |
| 141 | ''' If token is found in line, split line, add insert, and write; |
| 142 | else just write. ''' |
| 143 | |
| 144 | tmp_string = '' |
| 145 | |
| 146 | if line.count(token) > 0: |
| 147 | partials = line.split(token) |
| 148 | if insert_before: |
| 149 | tmp_string += insert |
| 150 | tmp_string += partials[0] + token + '\n' |
| 151 | else: |
| 152 | tmp_string += partials[0] + token + '\n' |
| 153 | tmp_string += insert |
| 154 | tmp_string += partials[1] |
| 155 | if len(partials) > 2: |
| 156 | for i, part in enumerate(partials): |
| 157 | if i > 1: |
| 158 | tmp_string += partials[i] + token |
| 159 | if fd is None: |
| 160 | return True, tmp_string |
| 161 | else: |
| 162 | fd.write(tmp_string) |
| 163 | return True |
| 164 | else: |
| 165 | if fd is None: |
| 166 | return False, line |
| 167 | else: |
| 168 | fd.write(line) |
| 169 | return False |