configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/maketheme.py
changeset 0 2e8eeb919028
child 3 e7e0ae78773e
equal deleted inserted replaced
-1:000000000000 0:2e8eeb919028
       
     1 #
       
     2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description: 
       
    15 #
       
    16 
       
    17 import re
       
    18 import os
       
    19 import sys
       
    20 import logging
       
    21 import xml.parsers.expat
       
    22 import unzip
       
    23 import shutil
       
    24 
       
    25 try:
       
    26     from cElementTree import ElementTree
       
    27 except ImportError:
       
    28     try:    
       
    29         from elementtree import ElementTree
       
    30     except ImportError:
       
    31         try:
       
    32             from xml.etree import cElementTree as ElementTree
       
    33         except ImportError:
       
    34             from xml.etree import ElementTree
       
    35 
       
    36 
       
    37 from cone.public import exceptions,plugin,utils,api
       
    38 from themeplugin import theme_function
       
    39 from theme_resource import ThemeResource
       
    40 from theme_container import ThemeContainer, ActiveTheme
       
    41 
       
    42 class ThemeImpl(plugin.ImplBase):
       
    43     """
       
    44     This class provides converting *.tpf files to target device
       
    45     
       
    46     
       
    47     Building process:
       
    48     1. All tpf files are founded in the cpf file according to "preinstalled directories" 
       
    49        and "CVC settings" which are defined in the thememl file.
       
    50        
       
    51     2. The tpf files are extracted to temporary directories. Every tpf file has self temporary directory
       
    52     
       
    53     3. *.tdf, *.svg files are builded to *.mbm, *.skn,... by using Carbide.UI command-line.
       
    54        The path of Carbide.UI is defined in the thememl file.
       
    55        
       
    56        Here is two possible cases:
       
    57          3a) The theme has defined UID number in thememl file.
       
    58              The Carbide.UI is run with parameter -uid %number%.
       
    59              Then this UID number (after converting to decimal format) is saved to
       
    60              platform setting in the step 5
       
    61     
       
    62           3b) The theme has not defined UID number
       
    63               The Carbide.UI is run without parameter -uid %number% and then
       
    64               the PID number is getted from *.pkg file and setted to platform setting in the decimal format
       
    65               in the step 5
       
    66 
       
    67     4. *.mbm, *.skn,... are copied to output directory according to content of the pkg file. 
       
    68        The *.pkg file contains the record where the *.mbm, *.skn,... are be copied.
       
    69        Sample: "themepackage.mbm" - "private\10207114\import\99d49b086e6097b8\themepackage.mbm"
       
    70 
       
    71     5. UID or PID number are saved to platform setting which is defined in the thememl file
       
    72     6. Temporary directories are removed
       
    73     """
       
    74 
       
    75     
       
    76     IMPL_TYPE_ID = "thememl"
       
    77     DEFAULT_INVOCATION_PHASE = 'pre'
       
    78     
       
    79     
       
    80     def __init__(self,ref,configuration):
       
    81         """
       
    82         Overloading the default constructor
       
    83         """
       
    84         plugin.ImplBase.__init__(self,ref,configuration)
       
    85         self.logger = logging.getLogger('cone.thememl')
       
    86         
       
    87     def build(self):
       
    88         """
       
    89         Building process of themes
       
    90         """
       
    91         # Get absolute path so that copying works correctly
       
    92         # despite working directory changing
       
    93         abs_output = os.path.abspath(os.path.join(self.output, "content"))
       
    94         
       
    95         # get *.tpf files from the configuration
       
    96         list_tpf = self.list_tpf_files(self.list_active_theme, self.list_theme_dir)
       
    97         
       
    98         theme_container = ThemeContainer(list_tpf,self.configuration)
       
    99         theme_container.carbide = self.carbide
       
   100         theme_container.create_themes()
       
   101         theme_container.prepare_active_themes(self.list_active_theme)
       
   102         theme_container.build_theme(self.theme_version)
       
   103         theme_container.copy_resources_to_output(abs_output)
       
   104         theme_container.set_active_PID_to_model()
       
   105         theme_container.removeTempDirs()
       
   106         
       
   107       
       
   108 
       
   109     def list_tpf_files(self,list_active_theme, list_theme_dir):
       
   110         """
       
   111         returns the list of tpf files which are in the configuration
       
   112         """
       
   113         list_tpf=[]
       
   114         default_view = self.configuration.get_default_view()
       
   115         
       
   116         for active_theme in list_active_theme:
       
   117             path=active_theme.get_setting_ref().replace("/",".")
       
   118             feature = default_view.get_feature(path+".localPath")
       
   119             setting = feature.get_data()
       
   120             if setting != None:
       
   121                 list_tpf.append(setting.get_value())    
       
   122         
       
   123         for theme_dir in list_theme_dir:
       
   124             theme_dir=theme_dir.replace("/",".")
       
   125             feature = default_view.get_feature(theme_dir+".localPath")
       
   126             setting = feature.get_data()
       
   127             if setting != None:
       
   128                 list_tpf.append(setting.get_value())
       
   129            
       
   130 
       
   131         return self.find_tpf_files(list_tpf) 
       
   132 
       
   133     
       
   134     def find_tpf_files(self, list_tpf_path):
       
   135         """
       
   136         finds *.tpf files in the data container
       
   137         """
       
   138         list_tpf={}
       
   139         
       
   140         datacontainer = self.configuration.layered_content()
       
   141         contentfiles = datacontainer.flatten()
       
   142         for reskey in contentfiles.keys():
       
   143             respath = contentfiles[reskey]
       
   144             
       
   145             if  respath.endswith(".tpf"):
       
   146                 # Strip file name from the resource path
       
   147                 respath_basename = os.path.split(respath)[0]
       
   148                 
       
   149                 for tpf_path in list_tpf_path:
       
   150                     # os.path.split() strips trailing slash, so do that here too
       
   151 
       
   152                     tpf_path = "/content/" + tpf_path 
       
   153                     if tpf_path.endswith(".tpf"):
       
   154                         if respath.endswith(tpf_path):
       
   155                             list_tpf[respath]=0
       
   156                             break
       
   157                     
       
   158                     if tpf_path.endswith('/'):
       
   159                         tpf_path = tpf_path.rstrip('/')
       
   160                     if respath_basename.endswith(tpf_path):
       
   161                         list_tpf[respath]=0
       
   162                         break
       
   163 
       
   164                         
       
   165                         
       
   166                         
       
   167                     
       
   168         return list_tpf.keys()    
       
   169                
       
   170 
       
   171     def generate(self, context=None):
       
   172         """
       
   173         Generate the given implementation.
       
   174         """
       
   175         self.parse_impl()
       
   176         self.build()
       
   177         
       
   178         return 
       
   179     
       
   180     def generate_layers(self,layers):
       
   181         """
       
   182         Generate the given Configuration layers.
       
   183         """
       
   184         self.logger.info('Generating layers %s' % layers)
       
   185         self.create_output(layers)
       
   186         return 
       
   187     
       
   188     def has_ref(self,ref):
       
   189         """
       
   190         @returns True if the implementation uses the given ref as input value.
       
   191         Otherwise return False.
       
   192         """
       
   193         return None
       
   194 
       
   195     def parse_impl(self):
       
   196         if self.configuration:
       
   197             resource =self.configuration.get_resource(self.ref)
       
   198             reader = ThemeImplReader()
       
   199             try:
       
   200                 self.logger.info('Parses %s' % self.ref)
       
   201                 reader.fromstring(resource.read())
       
   202                 self.carbide = reader.carbide
       
   203             except (SyntaxError),e:
       
   204                 logging.getLogger('cone.thememl(%s)' % resource.get_path()).error('Invalid xml in layer root file. Exception: %s' % (e))
       
   205                 raise exceptions.ParseError('Invalid xml in layer root file (%s). Exception: %s' % (resource.get_path(),e))
       
   206             self.list_theme_dir=reader.list_theme_dir
       
   207             self.list_active_theme=reader.list_active_theme
       
   208             self.theme_version = reader.theme_version
       
   209             resource.close()
       
   210 
       
   211         return 
       
   212     
       
   213     def list_output_files(self):
       
   214         """
       
   215         Return a list of output files as an array. 
       
   216         """
       
   217         # What to return if the output files cannot be known in advance?
       
   218         return []
       
   219     
       
   220 
       
   221 class ThemeImplReader(plugin.ReaderBase):
       
   222     """
       
   223     Parses a single thememl file
       
   224     """ 
       
   225     NAMESPACE = 'http://www.s60.com/xml/thememl/1'
       
   226     FILE_EXTENSIONS = ['thememl']
       
   227     
       
   228     def __init__(self):
       
   229         self.namespaces = [self.NAMESPACE]
       
   230         self.list_theme_dir = []
       
   231         self.list_active_theme = []
       
   232         self.theme_version = ""
       
   233         self.logger = logging.getLogger('cone.thememl')
       
   234         self.carbide = r"C:\Program Files\Nokia\Carbide.ui Theme Edition 3.4"
       
   235     
       
   236     @classmethod
       
   237     def read_impl(cls, resource_ref, configuration, etree):
       
   238         reader = ThemeImplReader()
       
   239         reader.parse_thememl(etree)
       
   240         
       
   241         impl = ThemeImpl(resource_ref, configuration)
       
   242         impl.list_theme_dir     = reader.list_theme_dir
       
   243         impl.list_active_theme  = reader.list_active_theme
       
   244         impl.theme_version      = reader.theme_version
       
   245         return impl
       
   246     
       
   247     def fromstring(self, xml_as_string):
       
   248         etree = ElementTree.fromstring(xml_as_string)
       
   249         self.parse_thememl(etree)
       
   250          
       
   251     def parse_thememl(self,etree):
       
   252         
       
   253         list_setting_uid={}
       
   254         
       
   255         #parses the version of the theme
       
   256         el_theme_version= etree.find("{%s}themeVersion" % self.namespaces[0])
       
   257         if el_theme_version != None:
       
   258             self.theme_version = el_theme_version.text
       
   259 
       
   260         car= etree.find("{%s}carbideuiPath" % self.namespaces[0])
       
   261         envpattern = ".*(%(.*)%).*"
       
   262         if car != None:
       
   263             mo = re.match(envpattern, car.text)
       
   264             if mo:
       
   265                 if os.environ.has_key(mo.group(2)):
       
   266                     self.carbide = car.text.replace(mo.group(1), os.environ[mo.group(2)])
       
   267                 else:
       
   268                     self.carbide = car.text 
       
   269             else:
       
   270                 self.carbide = car.text
       
   271 
       
   272         
       
   273         #parses the path of directories where are tpf files
       
   274         el_list_theme_dir = etree.findall("{%s}themeDir" % self.namespaces[0])
       
   275         for el_theme_dir in el_list_theme_dir:
       
   276             if el_theme_dir != None:
       
   277                 self.list_theme_dir.append(el_theme_dir.text)
       
   278             
       
   279         #parses the active themes and theirs ref setting and platform settings
       
   280         el_list_active_theme = etree.findall("{%s}activeTheme" % self.namespaces[0])
       
   281         for el_active_theme in el_list_active_theme:
       
   282             uid = el_active_theme.get("uid")
       
   283             active_theme = ActiveTheme()
       
   284             
       
   285             active_theme.set_uid(uid)
       
   286             for el_ref_setting in  el_active_theme.getiterator("{%s}refSetting" % self.namespaces[0]):
       
   287                 active_theme.set_setting_ref(el_ref_setting.text)
       
   288             
       
   289             
       
   290             for el_setting_uid in el_active_theme.getiterator("{%s}platformUID" % self.namespaces[0]): 
       
   291                 setting_uid = el_setting_uid.text
       
   292                 if list_setting_uid.has_key(setting_uid):
       
   293                     raise exceptions.ParseError('The file contains duplicate setting uid: %s' % setting_uid)
       
   294                 else:
       
   295                     list_setting_uid[setting_uid]=0
       
   296                     active_theme.set_setting_uids(setting_uid)
       
   297             
       
   298             self.list_active_theme.append(active_theme)