Welcome    Usage    Browse    Find CID    Search     Log in

cM API Documentation

module.py

Go to the documentation of this file.
00001 #
00002 # Collective Mind
00003 #
00004 # See cM LICENSE.txt for licensing details.
00005 # See cM Copyright.txt for copyright details.
00006 #
00007 # Developer(s): (C) Grigori Fursin, started on 2011.09
00008 #
00009 
00010 import os
00011 import shutil
00012 import json
00013 import urllib2
00014 import time
00015 import string
00016 import copy
00017 import getpass
00018 
00019 ini={}
00020 cm_kernel=None
00021 
00022 # ============================================================================
00023 def init(i):
00024 
00025     return {'cm_return':0}
00026 
00027 # ============================================================================
00028 def default(i):
00029 
00030     """
00031     Print general info about cM cmd
00032 
00033     Input:  {}
00034 
00035     Output: {
00036               cm_return - 0
00037             }
00038     """
00039 
00040     cm_kernel.print_for_con(cm_kernel.ini['dcfg']['cm_title'])
00041     cm_kernel.print_for_con('')
00042     cm_kernel.print_for_con('  Use "cm <module> help" or "cm <module> info" for more information.')
00043     return {'cm_return':0}
00044 
00045 
00046 # ============================================================================
00047 def help(i):
00048 
00049     """
00050     Print help about module actions
00051 
00052     Input:  {
00053               cm_run_module_uoa - module UOA
00054               (cm_common_func)  - if ='true', then the module is called from some other module
00055             }
00056 
00057     Output: {
00058               cm_return - 0
00059             }
00060     """
00061 
00062     cm_kernel.print_for_con(cm_kernel.ini['dcfg']['cm_title'])
00063 
00064     cm_kernel.print_for_con("")
00065     cm_kernel.print_for_con("  Module:")
00066     cm_kernel.print_for_con('    '+i['cm_run_module_uoa'])
00067 
00068     cm_kernel.print_for_con("")
00069     cm_kernel.print_for_con("  Module actions (cm <name_of_module> <action> <parameters>):")
00070 
00071     if 'cm_common_func' in i and i['cm_common_func']=='yes':
00072 
00073        r1={'cm_data_uoa':i['cm_run_module_uoa'],
00074            'cm_module_uoa':cm_kernel.ini['dcfg']['cmr_module']}
00075        if 'cm_repo_uoa' in i: r1['cm_repo_uoa']=i['cm_repo_uoa']
00076        r=load_data(r1)
00077        if r['cm_return']==0:
00078           d=r['cm_data_obj']
00079           if 'cm_actions' in d['cfg']:
00080              print_help({'cm_array':d['cfg']['cm_actions']})
00081     else:
00082        print_help({'cm_array':ini['cfg']['cm_actions']})
00083 
00084     if 'cm_common_actions' in ini['cfg']:
00085        cm_kernel.print_for_con('')
00086        cm_kernel.print_for_con('  Common actions:')
00087        print_help({'cm_array':ini['cfg']['cm_common_actions']})
00088 
00089     return {'cm_return':0}
00090 
00091 # ============================================================================
00092 def info(i):
00093 
00094     """
00095     Print info about module
00096 
00097     Input:  {
00098               cm_run_module_uoa - module UOA
00099               (cm_common_func)  - if ='true', then the module is called from some other module
00100             }
00101 
00102     Output: {
00103               cm_return - 0
00104             }
00105     """
00106 
00107     cm_kernel.print_for_con(cm_kernel.ini['dcfg']['cm_title'])
00108 
00109     cm_kernel.print_for_con('')
00110     cm_kernel.print_for_con('  Module:')
00111     cm_kernel.print_for_con('    '+i['cm_run_module_uoa'])
00112 
00113     if 'cm_common_func' in i and i['cm_common_func']=='yes':
00114        r=cm_kernel.load_data({'cm_module_uoa':cm_kernel.ini['dcfg']['cmr_module'],
00115                               'cm_data_uoa':i['cm_run_module_uoa']})
00116        if r['cm_return']==0:
00117           d=r['cm_data_obj']['cfg']
00118     else:
00119        d=ini['cfg']
00120 
00121     if 'cm_display_name' in d:
00122        cm_kernel.print_for_con('')
00123        cm_kernel.print_for_con('  Name:')
00124        cm_kernel.print_for_con('    '+d['cm_display_name'])
00125 
00126     if 'cm_description' in d:
00127        cm_kernel.print_for_con('')
00128        cm_kernel.print_for_con('  Description:')
00129        cm_kernel.print_for_con('    '+d['cm_description'])
00130 
00131     return {'cm_return':0}
00132 
00133 # ============================================================================
00134 def print_help(i):
00135     """
00136     Print help about data actions
00137 
00138     Input:  {
00139               cm_array - array in cM action format
00140             }
00141 
00142     Output: {
00143               cm_return - 0
00144             }
00145     """
00146 
00147     c=i['cm_array']
00148     for c1 in c:
00149         cm_kernel.print_for_con("")
00150         cm_kernel.print_for_con("    "+c1['cm_index']+":")
00151 
00152         if "desc" in c1:
00153            cm_kernel.print_for_con("      Description:  "+c1["desc"])
00154         if "params" in c1:
00155            cm_kernel.print_for_con("      Parameters:   "+c1["params"])
00156 
00157     return {'cm_return':0}
00158 
00159 # ============================================================================
00160 def gen_uid(i):
00161 
00162     """
00163     Generate cM UID
00164 
00165     Input:  {
00166                 (cm_console)       - by default, do not output anything except errors
00167                                      if 'txt' then output as plain text
00168                                      if 'web' then output for web (html, image, etc)
00169                                      if 'json' then output as json
00170             }
00171 
00172     Output: {
00173               cm_return - return code = 0, if successful
00174               cm_uid    - cM UID
00175             }
00176     """
00177 
00178     r=cm_kernel.gen_uid({})
00179     if r['cm_return']>0: return r
00180 
00181     if i.get('cm_console','')=='txt':
00182        cm_kernel.print_for_con(r['cm_uid'])
00183 
00184     return r
00185 
00186 # ============================================================================
00187 def register_func(i):
00188 
00189     """
00190     Register function (action) in a module
00191 
00192     Input:  {
00193               cm_run_module_uoa - module UOA
00194               (cm_common_func)  - if ='true', then the module is called from some other module
00195               (new_func)        - new function name
00196               (new_desc)        - new desc
00197               (new_index)       - new index (if empty, use func)
00198             }
00199 
00200     Output: {
00201               cm_return - 0
00202             }
00203     """
00204 
00205     txt=False
00206     if i.get('cm_console','')=='txt': txt=True
00207 
00208     # Load module
00209     cm_kernel.print_for_con('Loading module ...')
00210 
00211     m=i['cm_run_module_uoa']
00212 
00213     r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-module'],
00214                         'cm_action':'load',
00215                         'cm_data_uoa':m})
00216     if r['cm_return']>0: return r
00217 
00218     d=r['cm_data_obj']['cfg']
00219 
00220     a=d.get('cm_actions',[])
00221 
00222     if len(a)>0:
00223        cm_kernel.print_for_con('')
00224        cm_kernel.print_for_con('Available functions (actions):')
00225        
00226        cm_kernel.print_for_con('')
00227        for q in a:
00228            func=q['func']
00229            desc=q.get('desc','')
00230            index=q['cm_index']
00231 
00232            cm_kernel.print_for_con('  '+func+' ('+desc+')')
00233  
00234     new_func=i.get('new_func','')
00235     new_desc=i.get('new_desc','')
00236     new_index=i.get('new_index','')
00237 
00238     cm_kernel.print_for_con('')
00239 
00240     if new_func=='':
00241        if txt:
00242           new_func=raw_input('Enter new function name in module: ')
00243        else:
00244           return {'cm_return':1,'cm_error':'new_func is not defined'}
00245 
00246     if new_desc=='':
00247        if txt:
00248           new_desc=raw_input('Enter description of this function (optional): ')
00249        else:
00250           return {'cm_return':1,'cm_error':'new_func is not defined'}
00251 
00252     if new_index=='': new_index=new_func
00253 
00254     o={'func':new_func, 'desc':new_desc, 'cm_index':new_index}
00255 
00256     a.append(o)
00257     
00258     d['cm_actions']=a
00259 
00260     cm_kernel.print_for_con('')
00261     cm_kernel.print_for_con('Recording module description ...')
00262     
00263     r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-module'],
00264                         'cm_action':'update',
00265                         'cm_data_uoa':m,
00266                         'cm_array':d})
00267     if r['cm_return']>0: return r
00268 
00269     cm_kernel.print_for_con('')
00270     cm_kernel.print_for_con('Updated successfully ...')
00271 
00272     return {'cm_return':0}
00273 
00274 # ============================================================================
00275 def unregister_func(i):
00276 
00277     """
00278     Unregister function (action) in a module
00279 
00280     Input:  {
00281               cm_run_module_uoa - module UOA
00282               (cm_common_func)  - if ='true', then the module is called from some other module
00283               (func)            - new function name
00284             }
00285 
00286     Output: {
00287               cm_return - 0
00288             }
00289     """
00290 
00291     txt=False
00292     if i.get('cm_console','')=='txt': txt=True
00293 
00294     # Load module
00295     cm_kernel.print_for_con('Loading module ...')
00296 
00297     m=i['cm_run_module_uoa']
00298 
00299     r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-module'],
00300                         'cm_action':'load',
00301                         'cm_data_uoa':m})
00302     if r['cm_return']>0: return r
00303 
00304     d=r['cm_data_obj']['cfg']
00305 
00306     a=d.get('cm_actions',[])
00307 
00308     if len(a)>0:
00309        cm_kernel.print_for_con('')
00310        cm_kernel.print_for_con('Available functions (actions):')
00311        
00312        cm_kernel.print_for_con('')
00313        for q in a:
00314            func=q['func']
00315            desc=q.get('desc','')
00316            index=q['cm_index']
00317 
00318            cm_kernel.print_for_con('  '+func+' ('+desc+')')
00319  
00320     func=i.get('func','')
00321 
00322     cm_kernel.print_for_con('')
00323 
00324     if func=='':
00325        if txt:
00326           func=raw_input('Enter function name in module to unregister: ')
00327        else:
00328           return {'cm_return':1,'cm_error':'func is not defined'}
00329 
00330     found=False
00331     k=0
00332     for q in a:
00333         if q.get('func','')==func:
00334            found=True
00335            break
00336         k+=1
00337 
00338     if found:
00339        cm_kernel.print_for_con('')
00340        cm_kernel.print_for_con('Removing function from the module ...')
00341 
00342        del(a[k])
00343 
00344        d['cm_actions']=a
00345 
00346        cm_kernel.print_for_con('')
00347        cm_kernel.print_for_con('Recording module description ...')
00348        
00349        r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-module'],
00350                            'cm_action':'update',
00351                            'cm_data_uoa':m,
00352                            'cm_array':d})
00353        if r['cm_return']>0: return r
00354 
00355        cm_kernel.print_for_con('')
00356        cm_kernel.print_for_con('Updated successfully ...')
00357 
00358     else:
00359        return {'cm_return':1,'cm_error':'function name was not found in the module'}
00360 
00361     return {'cm_return':0}
00362 
00363 # ============================================================================
00364 def find_path_to_data(i):
00365 
00366     """
00367     Find path to data (to some extent we keep it here for compatibility or for
00368                        command line, since it's now the same as load_data).
00369     
00370 
00371     Input:  {
00372               See "load_data" function
00373             }
00374 
00375     Output: {
00376               See "load_data" function
00377             }
00378     """
00379 
00380     cc=''
00381     if 'cm_console' in i: cc=i['cm_console']
00382 
00383     i['cm_console']=''
00384     r=load_data(i)
00385     if r['cm_return']>0: return r
00386     i['cm_console']=cc
00387 
00388     if cc=='txt': cm_kernel.print_for_con(r['cm_path'])
00389 
00390     return r
00391 
00392 # ============================================================================
00393 def load_data(i):
00394 
00395     """
00396     Load data
00397 
00398     Input:  {
00399               cm_module_uoa  - module UOA
00400               cm_data_uoa    - data UOA 
00401               (cm_repo_uoa)  - repo UOA
00402               (cm_console)   - by default, do not output anything except errors
00403                                if 'txt' then output as plain text
00404                                if 'web' then output for web (html, image, etc)
00405                                if 'json' then output as json
00406               (cm_web)       - yes, for web environment
00407               (lock_acquire) - if 'yes', acquire lock
00408               (lock_expire)  - for how long to acquire lock (secs) 
00409               (cm_admin)     - if 'yes', override access control - only internal use,
00410                                can not be used during web access (explicitly removed)
00411             }                                   
00412     Output: {
00413               cm_return            - return code = 0, if successful
00414                                                  < 0, if error
00415                                                       32 - lock acquired by someone else
00416                                                            
00417               (cm_error)           - error text if return code > 0
00418               cm_data_obj          - cM data object
00419               cm_path              - path to data entry
00420               cm_path_module       - path to module entry with this data
00421               cm_uid               - uid (from UOA)
00422               cm_alias             - alias (from UOA)
00423               cm_display_as_alias  - taken from the data
00424               cm_repo_uoa          - UOA of a repository
00425               cm_repo_uid          - UID of a repository
00426               cm_display_html      - prepare display: "display as alias" or <I>alias</I> or UID
00427               (lock_uid)           - UID of the aquired lock
00428             }
00429     """
00430 
00431     # Prepare working data entry
00432     r1=i
00433 
00434 #    if cm_kernel.ini['loaded_data_by_path'].get('D:\\Work1\\CM\\cm-repos\\fgg-default\\.cmr\\repo\\fgg-default',{}).get('cm_path','')!='D:\\Work1\\CM\\cm-repos\\fgg-default\\.cmr\\repo\\fgg-default':
00435 #       raw_input('xyz3')
00436 
00437     # Build array of paths for repositories
00438     # Check if need to search through all repositories
00439     if r1.get('cm_repo_uoa','')!='':
00440        r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
00441                            'cm_action':'find_path_to_repository',
00442                            'find_repo_uoa':r1['cm_repo_uoa'],
00443                            'cm_admin':i.get('cm_admin','')})
00444        if r['cm_return']>0: return r
00445        r1['cm_path']=r['cm_path']
00446        r1['cm_repo_uid']=r['cm_uid']
00447     else:
00448        # Check if need to search through all repositories
00449        if 'cm_repo_search' in cm_kernel.ini['dcfg'] and cm_kernel.ini['dcfg']['cm_repo_search']=='all':
00450           r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
00451                               'cm_action':'get_all_repo_paths',
00452                               'cm_admin':i.get('cm_admin','')})
00453           if r['cm_return']>0: return r
00454 
00455           repos=r['cm_array']
00456           a=[]
00457 
00458           for x in repos:
00459               a.append(x['cm_path'])
00460 
00461           r1['cm_path_array']=a
00462 
00463     if 'cm_web' in i: r1['cm_web']=i['cm_web']
00464 
00465     # Load data
00466     r=cm_kernel.load_data(r1)
00467     if r['cm_return']>0: return r
00468     if r['cm_return']<0: 
00469        return {'cm_return':16, 'cm_error':'can\'t find path to data "'+r1['cm_data_uoa']+':'+r1['cm_module_uoa']+'"'}
00470 
00471     # Get repo UID:
00472     if 'cm_repo_uoa' in r1: 
00473        r['cm_repo_uoa']=r1['cm_repo_uoa']
00474        r['cm_repo_uid']=r1.get('cm_repo_uid','')
00475     else:
00476        for x in repos:
00477            if r['cm_path_repo']==x['cm_path']:
00478               r['cm_repo_uoa']=x['cm_uoa']
00479               r['cm_repo_uid']=x['cm_uid']
00480               break
00481 
00482     if i.get('cm_console', '')=='txt':
00483        cm_kernel.print_for_con(r['cm_data_obj']['cfg'])
00484 
00485     return r
00486 
00487 # ============================================================================
00488 def copy_data(i):
00489 
00490     """
00491     Copy data entry
00492 
00493     Input:  {
00494               (orig_repo_uoa)    - repo UOA of original data
00495               orig_module_uoa    - module of the data to copy
00496               orig_data_uoa      - original data UOA  
00497               (target_repo_uoa)  - target repo where to copy data 
00498                                    (if =='', repo of the original data is used)
00499               (target_data_uoa)  - target data UOA
00500 
00501               (target_data_uid)  - target data UID (if not set, original is used)
00502               (remove_alias)     - if 'yes', remove alias
00503               (generate_new_uid) - if 'yes', generate new target UID
00504               (overwrite)        - if 'yes' and target exists, overwrite
00505               (move)             - if 'yes', delete original after copy
00506               (cm_array_update)  - update data of created entry
00507             }                                   
00508     Output: {
00509               cm_return            - return code = 0, if successful
00510             }
00511     """
00512 
00513     ca=i.get('cm_array_update',{})
00514 
00515     move=i.get('move','')
00516     n1='copy'; n2='Copy'; n3='copied'
00517     if move=='yes': n1='move'; n2='Move'; n3='moved'
00518 
00519     # If web access, move to 'web' module
00520     if i.get('cm_console')=='web':
00521        # Get web style
00522        if 'cfg' in cm_kernel.ini['web_style']: web=cm_kernel.ini['web_style']['cfg']
00523        else:
00524           return {'cm_return':1, 'cm_error':'web style is not defined'}
00525 
00526        cm_kernel.print_for_con('<span class="cm-title">'+n2+' data</span><br>')
00527 
00528        # Detecting/restoring data from forms
00529        a1={}
00530        r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
00531                            'cm_action':'detect_form_params',
00532                            'cm_array':i, 
00533                            'cm_prefix':'#form1'})
00534        if r['cm_return']>0: return r
00535        cm_form_array1=r['cm_array']
00536        cm_form_commands1=r['cm_commands']
00537 
00538        # Get data description for this action
00539        r=cm_kernel.get_data_description({'cm_module_uoa':ini['cm_module_uid'], 
00540                                          'cm_action_key':'cm_common_actions',
00541                                          'cm_which_action':i['cm_action']})
00542        if r['cm_return']>0: return r
00543        cm_data_desc1=r['cm_data_desc']
00544        cm_params_default1=r['cm_params_default']
00545 
00546        # Check default
00547        forms_exists='yes'
00548        if len(cm_form_array1)==0:
00549           a1=cm_params_default1
00550 
00551           if i.get('browse_repo_uoa','')!='': a1['browse_repo_uoa']=i['browse_repo_uoa']
00552           if i.get('browse_module_uoa','')!='': a1['browse_module_uoa']=i['browse_module_uoa']
00553           if i.get('browse_data_uoa','')!='': a1['browse_data_uoa']=i['browse_data_uoa']
00554 
00555           forms_exists='no'
00556        else:
00557           r=cm_kernel.restore_flattened_array({'cm_array':cm_form_array1, 
00558                                                'cm_replace_in_keys':{'^35^':'#', '^64^':'@'}})
00559           if r['cm_return']>0: return r
00560           a1=r['cm_array']
00561 
00562        if 'cm_submit_'+n1+'_submit' not in i:
00563           cm_kernel.print_for_con('<FORM ACTION="" name="add_edit" METHOD="POST" enctype="multipart/form-data" accept-charset="utf-8">' )
00564 
00565           cm_kernel.print_for_con('  <input type="hidden" name="cm_menu" value="'+i.get('cm_menu','')+'">')
00566           cm_kernel.print_for_con('  <input type="hidden" name="cm_subaction_'+n1+'" value="'+i.get('cm_subaction_'+n1,'')+'">')
00567           if 'cm_back_json' in i:
00568              cm_kernel.print_for_web('  <input type="hidden" name="cm_back_json" value="'+i['cm_back_json']+'">')
00569 
00570           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
00571               'cm_action':'visualize_data',
00572               'cm_array':a1,
00573               'cm_data_desc':cm_data_desc1,
00574               'cm_form_commands':cm_form_commands1,
00575               'cm_separator':'#',
00576               'cm_separator_form':'#form1#',
00577               'cm_forms_exists':forms_exists,
00578               'cm_support_raw_edit':'no',
00579               'cm_mode':'add'}
00580           if 'cm_raw_edit' in i: ii['cm_raw_edit']=i['cm_raw_edit']
00581           if 'cm_back_json' in i: ii['cm_back_json']=i['cm_back_json']
00582           r=cm_kernel.access(ii)
00583           if r['cm_return']>0: return r
00584           cm_kernel.print_for_web(r['cm_string'])
00585 
00586           cm_kernel.print_for_con('<input type="submit" class="cm-button" name="cm_submit_'+n1+'_submit" value="'+n2+'">')
00587 
00588           cm_kernel.print_for_con('</FORM><br>')
00589        else:
00590           if a1.get('browse_repo_uoa','')!='': i['orig_repo_uoa']=a1['browse_repo_uoa']
00591           if a1.get('browse_module_uoa','')!='': i['orig_module_uoa']=a1['browse_module_uoa']
00592           if a1.get('browse_data_uoa','')!='': i['orig_data_uoa']=a1['browse_data_uoa']
00593 
00594           if a1.get('target_repo_uoa','')!='': i['target_repo_uoa']=a1['target_repo_uoa']
00595 
00596           if a1.get('overwrite','')!='': i['overwrite']=a1['overwrite']
00597           if a1.get('move','')!='': i['move']=a1['move']
00598 
00599           if a1.get('new_data_alias','')!='': i['target_data_uoa']=a1['new_data_alias']
00600           if a1.get('remove_alias','')!='': i['remove_alias']=a1['remove_alias']
00601           if a1.get('new_data_uid','')!='': i['target_data_uid']=a1['new_data_uid']
00602           if a1.get('generate_new_uid','')!='': i['generate_new_uid']=a1['generate_new_uid']
00603 
00604     # Copy / move
00605     if i.get('cm_console')!='web' or 'cm_submit_'+n1+'_submit' in i:
00606 
00607        # Check some vars
00608        omodule=i.get('orig_module_uoa','')
00609        if omodule=='': return {'cm_return':1,'cm_error':'parameter "orig_module_uoa" is not set in core/copy'}
00610        odata=i.get('orig_data_uoa','')
00611        if odata=='': return {'cm_return':1,'cm_error':'parameter "orig_data_uoa" is not set in core/copy'}
00612 
00613        orepo=i.get('orig_repo_uoa','')
00614        trepo=i.get('target_repo_uoa','')
00615        overwrite=i.get('overwrite','')
00616        move=i.get('move','')
00617 
00618        # Load original data
00619        ii={'cm_run_module_uoa':omodule,
00620            'cm_action':'load',
00621            'cm_data_uoa':odata}
00622        if orepo!='': ii['cm_repo_uoa']=orepo
00623        r=cm_kernel.access(ii)
00624        if r['cm_return']>0: return r
00625        orepo=r.get('cm_repo_uid','')
00626 
00627        dd=r['cm_data_obj']['cfg']
00628        if move!='yes':
00629           if dd.get('cm_display_as_alias','')!='':
00630              dd['cm_display_as_alias']+=' (copy)'
00631 
00632        po=r['cm_path']
00633 
00634        # Check target repo
00635        if trepo=='': trepo=r['cm_repo_uid']
00636 
00637        if ca!=None and len(ca)>0:
00638           r6=cm_kernel.merge_arrays({'cm_array':dd, 'cm_array1':ca})
00639           if r6['cm_return']>0: return r6
00640           dd=r6['cm_array']
00641 
00642        # Create target data
00643        ii={'cm_run_module_uoa':omodule,
00644            'cm_action':'add',
00645            'cm_repo_uoa':trepo,
00646            'cm_array':dd,
00647            'cm_skip_update_info':'yes'}
00648 
00649        if i.get('target_data_uoa','')!='': ii['cm_data_uoa']=i['target_data_uoa']
00650        else:                               
00651           if i.get('remove_alias','')!='yes': ii['cm_data_uoa']=r['cm_uoa']
00652 
00653        if i.get('target_data_uid','')!='': ii['cm_data_uid']=i['target_data_uid']
00654        else:                               
00655           if i.get('generate_new_uid','')!='yes': ii['cm_data_uid']=r['cm_uid']
00656 
00657        if overwrite=='yes' or (i.get('generate_new_uid','')!='yes' and 'cm_data_uoa' not in ii): 
00658           ii['cm_action']='update'
00659        else:
00660           ii['cm_action']='add'
00661 
00662        r=cm_kernel.access(ii)
00663        if r['cm_return']>0: return r
00664 
00665        pt=r['cm_path']
00666 
00667        # Copy files
00668        r=cm_kernel.get_list_of_all_files({'cm_path':po})
00669        if r['cm_return']>0: return r
00670 
00671        for q in r['cm_array']:
00672            po1=os.path.join(po,q)
00673            pt1=os.path.join(pt,q)
00674 
00675            pt1d=os.path.dirname(pt1)
00676            if not os.path.isdir(pt1d): os.makedirs(pt1d)
00677 
00678            if overwrite=='yes' and os.path.isfile(pt1): os.remove(pt1)
00679 
00680            shutil.copyfile(po1,pt1)
00681 
00682        # If move, delete original
00683        if move=='yes':
00684           ii={'cm_run_module_uoa':ini['cm_module_uid'],
00685               'cm_action':'delete',
00686               'cm_module_uoa':omodule,
00687               'cm_data_uoa':odata}
00688           if orepo!='': ii['cm_repo_uoa']=orepo
00689           r=cm_kernel.access(ii)
00690           if r['cm_return']>0: 
00691              cm_kernel.print_for_con('    Error deleting original data: '+r['cm_error'])
00692 
00693     if i.get('cm_console')=='web' and 'cm_submit_'+n1+'_submit' in i:
00694        cm_kernel.print_for_con('<BR>' )
00695        cm_kernel.print_for_con('Data '+n3+' successfully!' )
00696        cm_kernel.print_for_con('<BR><BR>' )
00697 
00698     return {'cm_return':0}
00699 
00700 # ============================================================================
00701 def rename_data(i):
00702 
00703     """
00704     Rename data entry
00705 
00706     Input:  {
00707               (orig_repo_uoa)  - repo of original data
00708               orig_module_uoa  - module of original data
00709               orig_data_uoa    - data UOA to rename
00710 
00711               new_data_alias   - new data alias (leave empty to remove alias)
00712               new_data_uid     - new data UID (leave empty to keep old one)
00713             }                                   
00714     Output: {
00715               cm_return            - return code = 0, if successful
00716             }
00717     """
00718 
00719     # If web access, move to 'web' module
00720     if i.get('cm_console')=='web':
00721        # Get web style
00722        if 'cfg' in cm_kernel.ini['web_style']: web=cm_kernel.ini['web_style']['cfg']
00723        else:
00724           return {'cm_return':1, 'cm_error':'web style is not defined'}
00725 
00726        cm_kernel.print_for_con('<span class="cm-title">Rename data</span><br>')
00727 
00728        # Detecting/restoring data from forms
00729        a1={}
00730        r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
00731                            'cm_action':'detect_form_params',
00732                            'cm_array':i, 
00733                            'cm_prefix':'#form1'})
00734        if r['cm_return']>0: return r
00735        cm_form_array1=r['cm_array']
00736        cm_form_commands1=r['cm_commands']
00737 
00738        # Get data description for this action
00739        r=cm_kernel.get_data_description({'cm_module_uoa':ini['cm_module_uid'], 
00740                                          'cm_action_key':'cm_common_actions',
00741                                          'cm_which_action':i['cm_action']})
00742        if r['cm_return']>0: return r
00743        cm_data_desc1=r['cm_data_desc']
00744        cm_params_default1=r['cm_params_default']
00745 
00746        # Check default
00747        forms_exists='yes'
00748        if len(cm_form_array1)==0:
00749           a1=cm_params_default1
00750 
00751           if i.get('browse_repo_uoa','')!='': a1['browse_repo_uoa']=i['browse_repo_uoa']
00752           if i.get('browse_module_uoa','')!='': a1['browse_module_uoa']=i['browse_module_uoa']
00753           if i.get('browse_data_uoa','')!='': a1['browse_data_uoa']=i['browse_data_uoa']
00754 
00755           forms_exists='no'
00756        else:
00757           r=cm_kernel.restore_flattened_array({'cm_array':cm_form_array1, 
00758                                                'cm_replace_in_keys':{'^35^':'#', '^64^':'@'}})
00759           if r['cm_return']>0: return r
00760           a1=r['cm_array']
00761 
00762        if 'cm_submit_rename_submit' not in i:
00763           cm_kernel.print_for_con('<FORM ACTION="" name="add_edit" METHOD="POST" enctype="multipart/form-data" accept-charset="utf-8">' )
00764 
00765           cm_kernel.print_for_con('  <input type="hidden" name="cm_menu" value="'+i.get('cm_menu','')+'">')
00766           cm_kernel.print_for_con('  <input type="hidden" name="cm_subaction_rename" value="'+i.get('cm_subaction_rename','')+'">')
00767           cm_kernel.print_for_con('  <input type="hidden" name="cm_module_uoa" value="'+i.get('cm_module_uoa','')+'">')
00768           cm_kernel.print_for_con('  <input type="hidden" name="browse_repo_uoa" value="'+a1.get('browse_repo_uoa','')+'">')
00769           cm_kernel.print_for_con('  <input type="hidden" name="browse_module_uoa" value="'+a1.get('browse_module_uoa','')+'">')
00770           cm_kernel.print_for_con('  <input type="hidden" name="browse_data_uoa" value="'+a1.get('browse_data_uoa','')+'">')
00771           if 'cm_back_json' in i:
00772              cm_kernel.print_for_web('  <input type="hidden" name="cm_back_json" value="'+i['cm_back_json']+'">')
00773 
00774           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
00775               'cm_action':'visualize_data',
00776               'cm_array':a1,
00777               'cm_data_desc':cm_data_desc1,
00778               'cm_form_commands':cm_form_commands1,
00779               'cm_separator':'#',
00780               'cm_separator_form':'#form1#',
00781               'cm_forms_exists':forms_exists,
00782               'cm_support_raw_edit':'no',
00783               'cm_mode':'add'}
00784           if 'cm_raw_edit' in i: ii['cm_raw_edit']=i['cm_raw_edit']
00785           if 'cm_back_json' in i: ii['cm_back_json']=i['cm_back_json']
00786           r=cm_kernel.access(ii)
00787           if r['cm_return']>0: return r
00788           cm_kernel.print_for_web(r['cm_string'])
00789 
00790           cm_kernel.print_for_con('<input type="submit" class="cm-button" name="cm_submit_rename_submit" value="Rename">')
00791 
00792           cm_kernel.print_for_con('</FORM><br>')
00793        else:
00794           if a1.get('browse_repo_uoa','')!='': i['orig_repo_uoa']=a1['browse_repo_uoa']
00795           if a1.get('browse_module_uoa','')!='': i['orig_module_uoa']=a1['browse_module_uoa']
00796           if a1.get('browse_data_uoa','')!='': i['orig_data_uoa']=a1['browse_data_uoa']
00797 
00798           if a1.get('new_data_alias','')!='': i['new_data_alias']=a1['new_data_alias']
00799           if a1.get('new_data_uid','')!='': i['new_data_uid']=a1['new_data_uid']
00800 
00801     # Rename
00802     if i.get('cm_console')!='web' or 'cm_submit_rename_submit' in i:
00803        # Load data
00804        ii={'cm_run_module_uoa':i.get('orig_module_uoa',''),
00805            'cm_action':'load'}
00806        if i.get('orig_repo_uoa','')!='': ii['cm_repo_uoa']=i['orig_repo_uoa']
00807        if i.get('orig_data_uoa','')!='': ii['cm_data_uoa']=i['orig_data_uoa']
00808        r=cm_kernel.access(ii)
00809        if r['cm_return']>0: return r
00810 
00811        p=r['cm_path']
00812        pm=r['cm_path_module']
00813        uid=r['cm_uid']
00814        uoa=r['cm_uoa']
00815        alias=r['cm_alias']
00816 
00817        if alias!='':
00818           p1=os.path.join(pm, cm_kernel.ini['dcfg']['dcm'], cm_kernel.ini['dcfg']['falias-a'] + alias)
00819           p2=os.path.join(pm, cm_kernel.ini['dcfg']['dcm'], cm_kernel.ini['dcfg']['falias-u'] + uid)
00820 
00821           if not os.path.isfile(p1):
00822              return {'cm_return':1, 'cm_error':'can\'t find part of alias description ('+p1+')'}
00823           if not os.path.isfile(p2):
00824              return {'cm_return':1, 'cm_error':'can\'t find part of alias description ('+p2+')'}
00825 
00826        # Target params
00827        ta=i.get('new_data_alias','')
00828        tu=i.get('new_data_uid','')
00829 
00830        if tu!='':
00831           if not cm_kernel.is_uid(tu):
00832              return {'cm_return':1, 'cm_error':'new data UID is not UID!'}
00833        else:
00834           tu=uid
00835 #          r=cm_kernel.gen_uid({})
00836 #          if r['cm_return']>0: return r
00837 #          tu=r['cm_uid']
00838 
00839        if ta!='': 
00840           p3=os.path.join(pm, cm_kernel.ini['dcfg']['dcm'], cm_kernel.ini['dcfg']['falias-a'] + ta)
00841           p4=os.path.join(pm, cm_kernel.ini['dcfg']['dcm'], cm_kernel.ini['dcfg']['falias-u'] + tu)
00842 
00843        # Rename main directory
00844        if ta!='': pt=os.path.join(pm,ta)
00845        else:      pt=os.path.join(pm,tu)
00846 
00847        if os.path.isdir(pt):
00848           return {'cm_return':1, 'cm_error':'new data UOA already exists'}
00849 
00850        os.rename(p,pt)
00851 
00852        if alias!='':
00853           os.remove(p1)
00854           os.remove(p2)
00855 
00856        if ta!='':
00857           fx=file(p3,'w')
00858           fx.write(tu+'\n')
00859           fx.close()
00860 
00861           fx=file(p4,'w')
00862           fx.write(ta+'\n')
00863           fx.close()
00864  
00865        # Check if need to index
00866        if cm_kernel.ini['dcfg'].get('use_indexing','')=='yes':
00867           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
00868               'cm_action':'index',
00869               'cm_module_uoa':i.get('orig_module_uoa',''),
00870               'cm_data_uoa':i.get('orig_data_uoa',''),
00871               'mode': 'delete'}
00872           if i.get('orig_repo_uoa','')!='': ii['cm_repo_uoa']=i['orig_repo_uoa']
00873           rx=cm_kernel.access(ii)
00874           # TBD: for now ignore output of indexing to avoid problems
00875 
00876        # Check if need to index
00877        if cm_kernel.ini['dcfg'].get('use_indexing','')=='yes':
00878           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
00879               'cm_action':'index',
00880               'cm_module_uoa':i.get('orig_module_uoa',''),
00881               'cm_data_uoa':tu,
00882               'mode': 'add'}
00883           if i.get('orig_repo_uoa','')!='': ii['cm_repo_uoa']=i['orig_repo_uoa']
00884           rx=cm_kernel.access(ii)
00885           # TBD: for now ignore output of indexing to avoid problems
00886 
00887 
00888     if i.get('cm_console')=='txt':
00889        q='Entry renamed successfully to '
00890        if ta!='': q+=ta+' ('+tu+')'
00891        else: q+=tu
00892        cm_kernel.print_for_con(q)
00893     elif i.get('cm_console')=='web' and 'cm_submit_rename_submit' in i:
00894        cm_kernel.print_for_con('<BR>' )
00895        cm_kernel.print_for_con('Data renamed successfully!' )
00896        cm_kernel.print_for_con('<BR><BR>' )
00897 
00898     return {'cm_return':0}
00899 
00900 # ============================================================================
00901 def add_data(i):
00902 
00903     """
00904     Add data
00905 
00906     Input:  {
00907               cm_module_uoa             - module UOA
00908               cm_data_uoa               - data UOA 
00909               (cm_data_uid)             - force data UID (if UOA is alias)
00910               (cm_repo_uoa)             - repo UOA
00911               (use_default_repo)        - if 'yes', use default repo
00912               (cm_console)              - by default, do not output anything except errors
00913                                            if 'txt' then output as plain text
00914                                            if 'web' then output for web (html, image, etc)
00915                                            if 'json' then output as json
00916 
00917               (cm_file_upload)          - text content of file for upload
00918               (cm_file_upload_base64)   - file content as base64.urlsafe_b64encode
00919     
00920               (cm_file_upload_name)     - preffered uploaded file name 
00921               (cm_file_upload_type)     - type of file (if .zip, it will be automatically unziped)
00922               (cm_archive)              - 'none'
00923                                           'already_archived_with_internal_name' - should save file 
00924                                             under default cM name (cm_archive.zip)
00925                                           'already_archived_with_user_name' - should save file under user name
00926 
00927               (cm_file_upload_tmp_uid)  - normally generated automatically by web server
00928                                           when uploading files
00929 
00930               cm_array                  - use ONLY this array to add data
00931               (cm_admin)                - if 'yes', override access control - only internal use,
00932                                           can not be used during web access (explicitly removed)
00933             }
00934 
00935     Output: {
00936               cm_return  - return code >0 if error
00937                                        -1 if entry exists
00938               cm_path    - path to created data entry
00939               cm_uid     - uid (from UOA)
00940               cm_alias   - alias (from UOA)
00941               cm_uoa     - alias or uid if alias==''
00942             }
00943     """                                            
00944     # If web access, move to 'web' module
00945     if i.get('cm_console')=='web':
00946        i['cm_run_module_uoa']=ini['cfg']['cm_modules']['cm-web']
00947        i['cm_action']='add_data_through_web'
00948        i['cm_mode']='add'
00949 
00950        r=cm_kernel.access(i)
00951        if r['cm_return']>0 or ('cm_subaction_add' in i and 'cm_subaction_add_submit' not in i) or r.get('cm_skip_report')=='yes': 
00952           return r
00953     else:
00954        # Check if writing is forbidden
00955        if cm_kernel.ini['dcfg'].get('forbid_write','')=='yes':
00956           return {'cm_return':1, 'cm_error':'any writing is forbidden by configuration'}
00957        elif cm_kernel.ini['dcfg'].get('allow_write_only_to_given_repositories','')=='yes':
00958           rx={'cm_return':1, 'cm_error':'writing is fobridden to this repository by configuration'}
00959           if 'repositories_for_writing_uoa' not in cm_kernel.ini['dcfg'] or ('cm_repo_uoa' not in i): 
00960              return rx
00961           # Load repository
00962           if 'cm_repo_uoa' in i and i['cm_repo_uoa']!='':
00963              ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
00964                  'cm_action':'load',
00965                  'cm_data_uoa':i['cm_repo_uoa'],
00966                  'cm_admin':i.get('cm_admin','')}
00967              rq=cm_kernel.access(ii)
00968              if rq['cm_return']>0: return rq
00969              if rq['cm_uid'] not in cm_kernel.ini['dcfg']['repositories_for_writing_uoa'] and \
00970                 rq['cm_uoa'] not in cm_kernel.ini['dcfg']['repositories_for_writing_uoa']:
00971                 return rx
00972 
00973        # Find path to work repository
00974        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
00975            'cm_action':'find_path_to_repository',
00976            'cm_admin':i.get('cm_admin','')}
00977        if 'cm_repo_uoa' in i: ii['find_repo_uoa']=i['cm_repo_uoa']
00978        if i.get('use_default_repo', '')=='yes': ii['get_default_repo']='yes'
00979        r=cm_kernel.access(ii)
00980        if r['cm_return']>0: return r
00981 
00982        # Check fine-grain access to repo
00983        ac=cm_kernel.ini['dcfg'].get('access_control',{})
00984        xcfg=r['cm_data_obj']['cfg']
00985        if i.get('cm_admin','')!='yes' and cm_kernel.ini['web']=='yes' and ac.get('use','')=='yes':
00986           rx=cm_kernel.access_control({'dcfg':xcfg, 'module_uoa':r['cm_module_uoa'], \
00987                                        'module_uid':r['cm_module_uid'], 'data_uoa':r['cm_uoa'], 'key':'write'})
00988           if rx['cm_return']>0: return rx
00989 
00990        i['cm_path']=r['cm_path']
00991 
00992        r=cm_kernel.create_data_entry(i)
00993        if r['cm_return']>0: return r
00994        elif r['cm_return']<0: 
00995           r.update({'cm_return':1, 'cm_error': 'data entry already exists'})
00996           return r
00997        else:
00998           # Check if need to index
00999           if cm_kernel.ini['dcfg'].get('use_indexing','')=='yes':
01000              ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
01001                  'cm_action':'index',
01002                  'cm_module_uoa':i['cm_module_uoa'],
01003                  'cm_data_uoa':r['cm_uid'],
01004                  'mode': 'add'}
01005              if 'cm_repo_uoa' in i: ii['cm_repo_uoa']=i['cm_repo_uoa']
01006              rx=cm_kernel.access(ii)
01007              # TBD: for now ignore output of indexing to avoid problems
01008 
01009     if i.get('cm_console')=='txt':
01010        cm_kernel.print_for_con('')
01011        cm_kernel.print_for_con('Entry added successfully!')
01012        cm_kernel.print_for_con('')
01013        cm_kernel.print_for_con('Path = '+r['cm_path'])
01014        cm_kernel.print_for_con('UID  = '+r['cm_uid'])
01015     elif i.get('cm_console')=='web' or i.get('cm_report_in_html')=='yes':
01016        cm_kernel.print_for_con('<B>Entry added successfully</B>!<BR>')
01017 
01018        if 'browse_module_uoa' in i: m=i['browse_module_uoa']
01019        else: m=i['cm_module_uoa']
01020 
01021        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01022            'cm_action':'convert_field_to_html',
01023            'cm_value':r['cm_uid'],
01024            'cm_key':'any_key',
01025            'cm_data_desc':{"type":"uoa", "cm_module_uoa":m},
01026            'cm_admin':i.get('cm_admin','')}
01027        if 'cm_back_json' in i: ii['cm_back_json']=i['cm_back_json']
01028        r1=cm_kernel.access(ii)
01029        if r1['cm_return']>0: cm_kernel.print_for_web('<B>cM error:</b> '+r1['cm_error'])
01030        else:                 cm_kernel.print_for_web('<BR>View entry: '+r1['cm_value_html'])
01031 
01032        # Print status
01033        if cm_kernel.ini['dcfg'].get('cm_show_info_after_add_update','')=='yes':
01034           cm_kernel.print_for_con('<BR>')
01035           cm_kernel.print_for_web('Path = <i>'+r['cm_path']+'</i><BR>')
01036 
01037     return r
01038 
01039 # ============================================================================
01040 def update_data(i):
01041 
01042     """
01043     Update data
01044 
01045     Input:  {
01046               cm_run_module_uoa | cm_module_uoa - module UOA
01047               cm_data_uoa                       - data UOA 
01048               (cm_data_uid)                     - force data UID (if UOA is alias)
01049               (cm_repo_uoa)                     - repo UOA
01050               (cm_console)                      - by default, do not output anything except errors
01051                                                   if 'txt' then output as plain text
01052                                                   if 'web' then output for web (html, image, etc)
01053                                                   if 'json' then output as json
01054               cm_array                          - use ONLY this array to update data
01055               (cm_skip_update_info)             - if yes, do not write 'cm_updated'
01056               (cm_update_only_index)            - update only index
01057 
01058               (cm_file_upload)                  - text content of file for upload
01059               (cm_file_upload_base64)           - file content as base64.urlsafe_b64encode
01060               (cm_file_upload_name)             - preffered uploaded file name 
01061               (cm_file_upload_type)             - type of file (if .zip, it will be automatically unziped)
01062               (cm_archive)                      - 'none'
01063                                                   'already_archived_with_internal_name' - should save file 
01064                                                     under default cM name (cm_archive.zip)
01065                                                   'already_archived_with_user_name' - should save file under user name
01066 
01067               (cm_file_upload_tmp_uid)          - normally generated automatically by web server
01068                                                   when uploading files
01069 
01070               (cm_add_default)                  - if 'yes', add default params from descriptions (module/kernel)
01071               (cm_description)                  - description of the data entry
01072               (cm_display_as_alias)             - user readable alias to display instead of module:data
01073 
01074               (cm_note)                         - note about this data entry
01075               (cm_like)                         - if 'yes' add +1 for this user to the entry
01076 
01077               ...                               - data to add to the repository if not set 'cm_array'
01078 
01079               (lock_uid)                        - UID of the aquired lock
01080             }
01081 
01082     Output: {
01083               cm_return  - return code >0 if error
01084                                        -1 if entry exists
01085               cm_path    - path to created data entry
01086               cm_uid     - uid (from UOA)
01087               cm_alias   - alias (from UOA)
01088               cm_uoa     - alias or uid if alias==''
01089             }
01090     """
01091 
01092     # If web access, move to 'web' module
01093     if i.get('cm_console')=='web':
01094        i['cm_run_module_uoa']=ini['cfg']['cm_modules']['cm-web']
01095        i['cm_action']='add_data_through_web'
01096        i['cm_mode']='update'
01097        r=cm_kernel.access(i)
01098        if r['cm_return']>0 or ('cm_subaction_update' in i and 'cm_subaction_update_submit' not in i) or r.get('cm_skip_report')=='yes': 
01099           return r
01100 
01101     else:
01102        # Check if writing is forbidden
01103        if cm_kernel.ini['dcfg'].get('forbid_write','')=='yes':
01104           return {'cm_return':1, 'cm_error':'any writing is forbidden by configuration'}
01105        elif cm_kernel.ini['dcfg'].get('allow_write_only_to_given_repositories','')=='yes':
01106           rx={'cm_return':1, 'cm_error':'writing is fobridden to this repository by configuration'}
01107           if 'repositories_for_writing_uoa' not in cm_kernel.ini['dcfg'] or ('cm_repo_uoa' not in i): 
01108              return rx
01109           # Load repository
01110           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
01111               'cm_action':'load',
01112               'cm_data_uoa':i['cm_repo_uoa']}
01113           rq=cm_kernel.access(ii)
01114           if rq['cm_return']>0: return rq
01115           if rq['cm_uid'] not in cm_kernel.ini['dcfg']['repositories_for_writing_uoa'] and \
01116              rq['cm_uoa'] not in cm_kernel.ini['dcfg']['repositories_for_writing_uoa']:
01117              return rx
01118 
01119        # Find path to data
01120        r=find_path_to_data(i)
01121        if r['cm_return']==0: 
01122           i['cm_path']=r['cm_path_repo']
01123        else:
01124           # Not found, then try to create a new one
01125           # Find path to work repository
01126           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
01127               'cm_action':'find_path_to_repository'}
01128           if 'cm_repo_uoa' in i: ii['find_repo_uoa']=i['cm_repo_uoa']
01129           r=cm_kernel.access(ii)
01130           if r['cm_return']>0: return r
01131 
01132           i['cm_path']=r['cm_path']
01133 
01134        # Check fine-grain access to either repo or data 
01135        # (both in one since above either data will be loaded or repo if new data is created)
01136        key_control='write'
01137        #If only note or like, use key 'comment'
01138        if len(i.get('cm_array',{}))==0 and \
01139           i.get('cm_file_upload','')=='' and \
01140           i.get('cm_file_upload_base64','')=='' and \
01141           i.get('cm_file_upload_tmp_uid','')=='' and \
01142           i.get('cm_upload_file_name','')=='' and \
01143           i.get('cm_add_default','')!='yes' and \
01144           i.get('cm_description','')=='' and \
01145           i.get('cm_display_as_alias','')=='' and \
01146           (i.get('cm_note','')!='' or i.get('cm_like','')!=''):
01147           key_control='comments'
01148 
01149        ac=cm_kernel.ini['dcfg'].get('access_control',{})
01150        xcfg=r['cm_data_obj']['cfg']
01151        if i.get('cm_admin','')!='yes' and cm_kernel.ini['web']=='yes' and ac.get('use','')=='yes':
01152           rx=cm_kernel.access_control({'dcfg':xcfg, 'module_uoa':r['cm_module_uoa'], \
01153                                        'module_uid':r['cm_module_uid'], 'data_uoa':r['cm_uoa'], 'key':key_control})
01154           if rx['cm_return']>0: return rx
01155 
01156        # Create or update data entry
01157        i['cm_update']='yes'
01158        r=cm_kernel.create_data_entry(i)
01159        if r['cm_return']>0: return r
01160 
01161        # Check if need to index
01162        if cm_kernel.ini['dcfg'].get('use_indexing','')=='yes':
01163           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
01164               'cm_action':'index',
01165               'cm_module_uoa':i['cm_module_uoa'],
01166               'cm_data_uoa':r['cm_uid'],
01167               'mode': 'add'}
01168           if 'cm_repo_uoa' in i: ii['cm_repo_uoa']=i['cm_repo_uoa']
01169           rx=cm_kernel.access(ii)
01170           # TBD: for now ignore output of indexing to avoid problems
01171 
01172     if i.get('cm_console')=='txt':
01173        cm_kernel.print_for_con('Entry updated successfully!')
01174        cm_kernel.print_for_con('')
01175        cm_kernel.print_for_con('Path = '+r['cm_path'])
01176        cm_kernel.print_for_con('UID  = '+r['cm_uid'])
01177     elif i.get('cm_console')=='web' or i.get('cm_report_in_html')=='yes':
01178        cm_kernel.print_for_con('<B>Entry updated successfully</B>!<BR>')
01179 
01180        if 'browse_module_uoa' in i: m=i['browse_module_uoa']
01181        else: m=i['cm_module_uoa']
01182 
01183        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01184            'cm_action':'convert_field_to_html',
01185            'cm_value':r['cm_uid'],
01186            'cm_key':'any_key',
01187            'cm_data_desc':{"type":"uoa", "cm_module_uoa":m}}
01188        if 'cm_back_json' in i: ii['cm_back_json']=i['cm_back_json']
01189        r1=cm_kernel.access(ii)
01190        if r1['cm_return']>0: cm_kernel.print_for_web('<B>cM error:</b> '+r1['cm_error'])
01191        else:                 cm_kernel.print_for_web('<BR>View entry: '+r1['cm_value_html'])
01192 
01193        if cm_kernel.ini['dcfg'].get('cm_show_info_after_add_update','')=='yes':
01194           cm_kernel.print_for_con('<BR>')
01195           cm_kernel.print_for_web('Path = <i>'+r['cm_path']+'</i><BR>')
01196 
01197     return r
01198 
01199 # ============================================================================
01200 def view_data(i):
01201 
01202     """
01203     View data
01204 
01205     Input:  {
01206               cm_module_uoa   - module UOA
01207               cm_data_uoa     - data UOA 
01208               (cm_repo_uoa)   - repo UOA
01209               (cm_console)    - by default, do not output anything except errors
01210                                 if 'txt' then output as plain text
01211                                 if 'web' then output for web (html, image, etc)
01212                                 if 'json' then output as json
01213               (cm_back)       - for back button
01214             }
01215 
01216     Output: {
01217               cm_return   - return code >0 if error
01218                                         -1 if entry exists
01219               cm_path     - path to data entry
01220               cm_uid      - uid (from UOA)
01221               cm_alias    - alias (from UOA)
01222               cm_data_obj - cM data obj (cm_data_obj['cfg'] - data entry json)
01223             }
01224 
01225     """
01226 
01227     cc=''
01228     if 'cm_console' in i: cc=i['cm_console']
01229 
01230     # If web access, move to 'web' module
01231     if cc=='web':
01232        i['cm_run_module_uoa']=ini['cfg']['cm_modules']['cm-web']
01233        i['cm_action']='view_data_through_web'
01234        return cm_kernel.access(i)
01235 
01236     # Load data
01237     i['cm_console']=''
01238     rdata=load_data(i)
01239     if rdata['cm_return']>0: return rdata
01240     d=rdata['cm_data_obj']
01241     p=rdata['cm_path']
01242 
01243     # Start visualization
01244     if cc=='txt': cm_kernel.print_for_con(json.dumps(d, indent=2))
01245 
01246     return rdata
01247 
01248 # ============================================================================
01249 def delete_data(i):
01250 
01251     """
01252     Delete data
01253 
01254     Input:  {
01255               cm_run_module_uoa | cm_module_uoa - module UOA
01256               cm_data_uoa                       - data UOA 
01257               (cm_repo_uoa)                     - repo UOA
01258               (cm_force_delete)                 - if 'yes', force delete
01259               (cm_console)                      - by default, do not output anything except errors
01260                                                   if 'txt' then output as plain text
01261                                                   if 'web' then output for web (html, image, etc)
01262                                                   if 'json' then output as json
01263               (cm_admin)                        - if 'yes', override access control - only internal use,
01264                                                   can not be used during web access (explicitly removed)
01265             }
01266 
01267     Output: {
01268               cm_return  - return code >0 if error
01269                                        -1 if entry exists
01270             }
01271     """
01272 
01273     cc=''
01274     if 'cm_console' in i: cc=i['cm_console']
01275 
01276     # If web access, move to 'web' module
01277     if cc=='web':
01278        i['cm_run_module_uoa']=ini['cfg']['cm_modules']['cm-web']
01279        i['cm_action']='delete_data_through_web'
01280        return cm_kernel.access(i)
01281 
01282     # If cm_module_uoa is not defined or core, find current one as well as default repo and possibly default data
01283     if 'cm_module_uoa' not in i or i['cm_module_uoa']==ini['cm_module_uid'] or i['cm_module_uoa']=='core':
01284        rx=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
01285                             'cm_action':'find_path_to_repository'})
01286        if rx['cm_return']>0: return rx
01287        if rx.get('cur_module_uoa','')!='':
01288           i['cm_module_uoa']=rx['cur_module_uoa']
01289        if rx.get('cur_data_uoa','')!='':
01290           p=os.path.join(rx['cm_path'], rx['cur_module_uoa'])
01291           i['cm_data_uoa']=rx['cur_data_uoa']
01292           os.chdir(p)
01293        if rx.get('cm_uoa','')!='':
01294           i['cm_repo_uoa']=rx['cm_uoa']
01295 
01296     # Find working data entry
01297     r1=copy.deepcopy(i)
01298 
01299     # If cm_data_uoa is not defined
01300     data_to_delete=[]
01301     if i.get('cm_data_uoa','')=='':
01302        jj={'cm_run_module_uoa':i.get('cm_module_uoa',''),
01303            'cm_action':'list'}
01304        if i.get('cm_repo_uoa','')!='': jj['cm_repo_uoa']=i['cm_repo_uoa']
01305        r2=cm_kernel.access(jj)
01306        if r2['cm_return']>0: return r2
01307 
01308        for q in r2['cm_mixed']:
01309            data_to_delete.append(q['cm_uid'])
01310 
01311     else:
01312        data_to_delete.append(i['cm_data_uoa'])
01313 
01314     for q in data_to_delete:
01315        jj={'cm_module_uoa':r1.get('cm_module_uoa',''),
01316            'cm_data_uoa':q}
01317        if r1.get('cm_repo_uoa','')!='': jj['cm_repo_uoa']=r1['cm_repo_uoa']
01318 
01319        # Find path to data
01320        r=find_path_to_data(jj)
01321        if r['cm_return']>0: return r
01322 
01323        # Check fine-grain access to either repo or data 
01324        # (both in one since above either data will be loaded or repo if new data is created)
01325        ac=cm_kernel.ini['dcfg'].get('access_control',{})
01326        xcfg=r['cm_data_obj']['cfg']
01327        if i.get('cm_admin','')!='yes' and cm_kernel.ini['web']=='yes' and ac.get('use','')=='yes':
01328           rx=cm_kernel.access_control({'dcfg':xcfg, 'module_uoa':r['cm_module_uoa'], \
01329                                        'module_uid':r['cm_module_uid'], 'data_uoa':r['cm_uoa'], 'key':'write'})
01330           if rx['cm_return']>0: return rx
01331 
01332        # Check if writing is forbidden
01333        if cm_kernel.ini['dcfg'].get('forbid_write','')=='yes':
01334           return {'cm_return':1, 'cm_error':'any writing is forbidden by configuration'}
01335        elif cm_kernel.ini['dcfg'].get('allow_write_only_to_given_repositories','')=='yes':
01336           rx={'cm_return':1, 'cm_error':'writing is fobridden to this repository by configuration'}
01337           if 'repositories_for_writing_uoa' not in cm_kernel.ini['dcfg'] or ('cm_repo_uoa' not in r1 and 'cm_repo_uoa' not in r): 
01338              return rx
01339           # Load repository
01340           cm_repo_uoa=''
01341           if 'cm_repo_uoa' in r1: cm_repo_uoa=r1['cm_repo_uoa']
01342           if 'cm_repo_uoa' in r: cm_repo_uoa=r['cm_repo_uoa']
01343           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
01344               'cm_action':'load',
01345               'cm_data_uoa':cm_repo_uoa}
01346           rq=cm_kernel.access(ii)
01347           if rq['cm_return']>0: return rq
01348           if rq['cm_uid'] not in cm_kernel.ini['dcfg']['repositories_for_writing_uoa'] and \
01349              rq['cm_uoa'] not in cm_kernel.ini['dcfg']['repositories_for_writing_uoa']:
01350              return rx
01351 
01352        to_delete=True
01353 
01354        if cc=='txt' and i.get('cm_force_delete','')!='yes':
01355           cm_kernel.print_for_con('You are about to delete '+r['cm_path'])
01356           check=raw_input('Are you sure (Y/N) ?')
01357 
01358           if check!='Y' and check!='y': to_delete=False
01359 
01360        if to_delete:
01361           # Check if need to index
01362           if cm_kernel.ini['dcfg'].get('use_indexing','')=='yes':
01363              ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
01364                  'cm_action':'index',
01365                  'cm_module_uoa':r1['cm_module_uoa'],
01366                  'cm_data_uoa':r1['cm_data_uoa'],
01367                  'mode': 'delete'}
01368              if 'cm_repo_uoa' in i: ii['cm_repo_uoa']=i['cm_repo_uoa']
01369              rx=cm_kernel.access(ii)
01370              # TBD: for now ignore output of indexing to avoid problems
01371 
01372           ii={'cm_path':r['cm_path'], 'cm_path_module':r['cm_path_module'], 'cm_alias':r['cm_alias'], 'cm_uid':r['cm_uid']}
01373           if 'cm_user_uoa' in i: ii['cm_user_uoa']=i['cm_user_uoa']
01374           r2=cm_kernel.delete_entry(ii)
01375           if r2['cm_return']>0: return r2
01376           elif r2['cm_return']==0 and i.get('cm_console','')=='txt':
01377              cm_kernel.print_for_con('Entry '+q+' successfully deleted!')
01378 
01379     return {'cm_return':0}
01380 
01381 # ============================================================================
01382 def list_data(i):
01383 
01384     """
01385     List data
01386 
01387     Input:  {
01388               cm_run_module_uoa | cm_module_uoa - module UOA
01389               (cm_repo_uoa)                     - repo UOA
01390               (cm_data_uoa)                     - data UOA
01391               (cm_console)                      - by default, do not output anything except errors
01392                                                   if 'txt' then output as plain text
01393                                                   if 'web' then output for web (html, image, etc)
01394                                                   if 'json' then output as json
01395               (cm_only_uid)                     - 'yes' to show only UID
01396               (cm_class_uoa)                    - prune by 1 class UOA
01397                    or
01398               (cm_classes_uoa)                  - prune by classes UOA (list)
01399               (cm_only_available_modules)       - if 'yes', return only available modules in a given repository
01400               (skip_data_cfg)                   - if 'yes', do not add data cfg            
01401               (show_alias_and_uid)              - if 'yes', show alias (UID)
01402               (show_display_as_alias)           - if 'yes', show in format DISPLAY_AS_ALIAS (UID / ALIAS)
01403             }
01404 
01405     Output: {
01406               cm_return  - return code >0 if error
01407                                        -1 if entry exists
01408               cm_array   - array with UOA
01409               cm_mixed   - list of {cm_uid, cm_alias, cm_uoa, cm_display_as_alias, cm_display_html}
01410             }
01411     """
01412 
01413     # Prepare working data entry
01414     r1=i
01415 
01416     # Build array of paths for repositories
01417     # Check if need to search through all repositories
01418     a=[]
01419     if 'cm_repo_uoa' in r1 and r1['cm_repo_uoa']!='':
01420        r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
01421                            'cm_action':'find_path_to_repository',
01422                            'find_repo_uoa':r1['cm_repo_uoa']})
01423        if r['cm_return']>0: return r
01424 
01425        a.append(r['cm_path'])
01426     else:
01427        # Check if need to search through all repositories
01428        if 'cm_repo_search' in cm_kernel.ini['dcfg'] and cm_kernel.ini['dcfg']['cm_repo_search']=='all':
01429           r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
01430                               'cm_action':'get_all_repo_paths'})
01431           if r['cm_return']>0: return r
01432 
01433           for x in r['cm_array']:
01434               a.append(x['cm_path'])
01435 
01436     if 'cm_only_uid' in i: r1['cm_only_uid']=i['cm_only_uid']
01437     if 'cm_mixed' in i: r1['cm_mixed']=i['cm_mixed']
01438     if i.get('skip_data_cfg','')!='': r1['skip_data_cfg']=i['skip_data_cfg']
01439 
01440     b=[]
01441     c=[]
01442     balias={}
01443     dalias={}
01444     for x in a:
01445         r1['cm_path']=x
01446         # Obtain list of data from the repository
01447         if i.get('cm_class_uoa','')!='': r1['cm_classes_uoa']=[i['cm_class_uoa']]
01448         elif 'cm_classes_uoa' in i: r1['cm_classes_uoa']=i['cm_classes_uoa']
01449         if 'cm_data_uoa' in i: r1['cm_data_uoa']=i['cm_data_uoa']
01450         r=cm_kernel.get_all_uoa(r1)
01451         if r['cm_return']>0: return r
01452 
01453         for x in r['cm_array']:
01454             b.append(x)
01455 
01456         for x in r['cm_mixed']:
01457             c.append(x)
01458             if x.get('cm_alias','')!='': balias[x['cm_alias']]=x['cm_uid']
01459             if x.get('cm_display_as_alias','')!='': dalias[x['cm_uoa']]=x['cm_display_as_alias']
01460 
01461     b.sort()
01462 
01463     # Check if should output
01464     if i.get('cm_console','')=='txt':
01465        for x in b:
01466            q1=balias.get(x,'')
01467 
01468            if i.get('show_display_as_alias','')=='yes' and dalias.get(x,'')!='':
01469               q='"'+dalias[x]+'"  ('
01470               if q1=='': q+=x+')'
01471               else:      q+=x+' / '+q1+')'
01472            else:
01473               q=x
01474               if i.get('show_alias_and_uid','')=='yes' and q1!='':
01475                  q+=' ('+q1+')'
01476 
01477            cm_kernel.print_for_con(q)
01478 
01479     return {'cm_return':0, 'cm_array':b, 'cm_mixed':c}
01480 
01481 # ============================================================================
01482 def find_cid (i):
01483 
01484     """
01485     Find CID
01486 
01487     Input:  {
01488             }
01489 
01490     Output: {
01491               cm_return  - return code >0 if error
01492             }
01493     """
01494 
01495     # Check styles, etc
01496     if 'cfg' in cm_kernel.ini['web_style']: web=cm_kernel.ini['web_style']['cfg']
01497     else:
01498        return {'cm_return':1, 'cm_error':'web style is not defined'}
01499 
01500     cm_kernel.print_for_con("<B>Find data by CID or explicitly:</B><br><br>")
01501     ######################################################################
01502     if 'cm_subaction_find_cid_submit' not in i:
01503        cm_kernel.print_for_web('<FORM ACTION="'+web['http_prefix']+'cm_menu=find_cid" METHOD="POST">')
01504 
01505        cm_kernel.print_for_web(web['table_init']+'<tr><td>')
01506        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01507            'cm_action':'convert_field_to_html',
01508            'cm_value':'',
01509            'cm_key':'cm_find_cid',
01510            'cm_mode':'add',
01511            'cm_data_desc':{"type":"text"}}
01512        r1=cm_kernel.access(ii)
01513        if r1['cm_return']>0: 
01514           cm_kernel.print_for_web('<B>cM error:</b> '+r1['cm_error'])
01515        else:
01516           cm_kernel.print_for_web('<small><b>Data CID:</b></small> '+r1['cm_value_html'])
01517        cm_kernel.print_for_con('</td></tr></table>')
01518 
01519        cm_kernel.print_for_con('<small><i>or</i></small><BR>')
01520 #       cm_kernel.print_for_con('<TABLE BORDER="1"><TR>')
01521        cm_kernel.print_for_web(web['table_init'])
01522 
01523        # Input repo
01524        cm_kernel.print_for_con('<tr><TD><small><b>Repository UOA:</b></small></TD>')
01525        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01526            'cm_action':'convert_field_to_html',
01527            'cm_value':'',
01528            'cm_key':'cm_find_repo_uoa',
01529            'cm_mode':'add',
01530            'cm_data_desc':{"type":"text"}}
01531        r1=cm_kernel.access(ii)
01532        if r1['cm_return']>0: 
01533           cm_kernel.print_for_web('<B>cM error:</b> '+r1['cm_error'])
01534        else:
01535           cm_kernel.print_for_web('<TD>'+r1['cm_value_html']+'</TD></tr>')
01536 
01537        # Input module
01538        cm_kernel.print_for_con('<tr><TD><small><b>Module UOA:</b></small></TD>')
01539        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01540            'cm_action':'convert_field_to_html',
01541            'cm_value':'',
01542            'cm_key':'cm_find_module_uoa',
01543            'cm_mode':'add',
01544            'cm_data_desc':{"type":"text"}}
01545        r1=cm_kernel.access(ii)
01546        if r1['cm_return']>0: 
01547           cm_kernel.print_for_web('<B>cM error:</b> '+r1['cm_error'])
01548        else:
01549           cm_kernel.print_for_web('<TD>'+r1['cm_value_html']+'</TD></tr>')
01550 
01551        # Input data
01552        cm_kernel.print_for_con('<tr><TD><small><b>Data UOA:</b></small></TD>')
01553        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01554            'cm_action':'convert_field_to_html',
01555            'cm_value':'',
01556            'cm_key':'cm_find_data_uoa',
01557            'cm_mode':'add',
01558            'cm_data_desc':{"type":"text"}}
01559        r1=cm_kernel.access(ii)
01560        if r1['cm_return']>0: 
01561           cm_kernel.print_for_web('<B>cM error:</b> '+r1['cm_error'])
01562        else:
01563           cm_kernel.print_for_web('<TD>'+r1['cm_value_html']+'</TD></tr>')
01564 
01565        cm_kernel.print_for_con('</TABLE>')
01566 
01567        cm_kernel.print_for_con('<br>')
01568 
01569        cm_kernel.print_for_web('<input type="hidden" name="cm_back_json" value="'+json.dumps(ii).replace('"','&quot;')+'">')
01570 
01571        cm_kernel.print_for_con('<input type="submit" class="cm-button" name="cm_subaction_find_cid_submit" value="Find">')
01572        cm_kernel.print_for_con('</FORM><br>')
01573 
01574     ######################################################################
01575     else:
01576        # Find data
01577        ii={}
01578        if 'cm_find_cid' in i and i['cm_find_cid']!='': 
01579           rx=cm_kernel.cid2array({'cid':i['cm_find_cid']})
01580           if rx['cm_return']>0: return rx
01581           ii.update(rx['cm_array'])
01582        else:
01583           if i.get('cm_find_repo_uoa','')!='': ii['cm_repo_uoa']=i['cm_find_repo_uoa']
01584           if i.get('cm_find_module_uoa','')!='': ii['cm_module_uoa']=i['cm_find_module_uoa']
01585           if i.get('cm_find_data_uoa')!='': ii['cm_data_uoa']=i['cm_find_data_uoa']
01586 
01587        r1=find_path_to_data(ii)
01588        if r1['cm_return']>0:
01589           cm_kernel.print_for_con('Can\'t find entry!')
01590        else:
01591           ii1={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01592                'cm_action':'convert_field_to_html',
01593                'cm_value':r1['cm_uoa'],
01594                'cm_key':'any_key',
01595                'cm_data_desc':{"type":"uoa", "cm_module_uoa":ii['cm_module_uoa']}}
01596           if 'cm_back' in i: ii1.update({'cm_back':i['cm_back']})
01597           if 'cm_user_uoa' in i: ii1['cm_user_uoa']=i['cm_user_uoa']
01598           r1=cm_kernel.access(ii1)
01599           if r1['cm_return']>0: 
01600              cm_kernel.print_for_web('<B>cM error:</b> '+r1['cm_error'])
01601           else:
01602              cm_kernel.print_for_web('View entry: '+r1['cm_value_html'])
01603 
01604        cm_kernel.print_for_con('<BR>')
01605        cm_kernel.print_for_con('<BR>')
01606 
01607     return {'cm_return':0}
01608 
01609 # ============================================================================
01610 def repair(i):
01611 
01612     """
01613     Repair data entry (most common - alias exist but not UID)
01614 
01615     Input:  {
01616               See "load_data"
01617             }
01618 
01619     Output: {
01620               cm_return   - return code = 0 if success
01621               See "load_data"
01622             }
01623     """
01624 
01625     # Prepare working data entry
01626     r1=i
01627 
01628     # Check if writing is forbidden
01629     if cm_kernel.ini['dcfg'].get('forbid_write','')=='yes':
01630        return {'cm_return':1, 'cm_error':'any writing is forbidden by configuration'}
01631     elif cm_kernel.ini['dcfg'].get('allow_write_only_to_given_repositories','')=='yes':
01632        rx={'cm_return':1, 'cm_error':'writing is fobridden to this repository by configuration'}
01633        if 'repositories_for_writing_uoa' not in cm_kernel.ini['dcfg'] or ('cm_repo_uoa' not in r1): 
01634           return rx
01635        # Load repository
01636        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
01637            'cm_action':'load',
01638            'cm_data_uoa':r1['cm_repo_uoa']}
01639        rq=cm_kernel.access(ii)
01640        if rq['cm_return']>0: return rq
01641        if rq['cm_uid'] not in cm_kernel.ini['dcfg']['repositories_for_writing_uoa'] and \
01642           rq['cm_uoa'] not in cm_kernel.ini['dcfg']['repositories_for_writing_uoa']:
01643           return rx
01644 
01645     # Find path to data
01646     r=load_data(r1)
01647     if r['cm_return']==0: 
01648        cm_kernel.print_for_con('Nothing to repair')
01649     else:
01650        if r['cm_return']==10:
01651           cm_kernel.print_for_con('Inconsistent entry detected - alias exists but not UID - trying to repair ...')
01652 
01653           # check if has .cm and data.json
01654           p=os.path.join(r['cm_path'], cm_kernel.ini['dcfg']['dcm'])
01655           if os.path.isdir(p):
01656              p1=os.path.join(p, cm_kernel.ini['dcfg']['fconfig']) 
01657              if os.path.isfile(p1):
01658                 return {'cm_return':1, 'cm_error': 'file '+p1+' already exists, hence can\'t repair'}
01659 
01660           src=r['cm_path']
01661           dst=os.path.join(r['cm_path_orig'], r1['cm_data_uoa']+'.tmp')
01662           cm_kernel.print_for_con('')
01663           cm_kernel.print_for_con('Renaming '+src+' to '+dst+' ...')
01664           
01665           r2=shutil.move(src, dst) 
01666 
01667           path_repo=os.path.split(r['cm_path_orig'])[0]
01668 
01669           cm_kernel.print_for_con('')
01670           cm_kernel.print_for_con('Trying to add a new entry '+r1['cm_data_uoa'])
01671 
01672           ii={'cm_path': path_repo,
01673               'cm_module_uoa': r1['cm_module_uoa'],
01674               'cm_data_uoa': r1['cm_data_uoa']}
01675           if 'cm_array' in i:            ii['cm_array']=i['cm_array']
01676           if 'cm_user_uoa' in i:         ii['cm_user_uoa']=i['cm_user_uoa']
01677           if 'cm_note' in i:             ii['cm_note']=i['cm_note']
01678           if 'cm_like' in i:             ii['cm_like']=i['cm_like']
01679           if 'cm_description' in i:      ii['cm_description']=i['cm_description']
01680           if 'cm_display_as_alias' in i: 
01681              ii['cm_display_as_alias']=i['cm_display_as_alias']
01682           else:
01683              ii['cm_display_as_alias']=r1['cm_data_uoa'].lower().replace(' ','_')
01684           r2=cm_kernel.create_data_entry(ii)
01685           if r2['cm_return']>0: return r2
01686 
01687           # move data back
01688           cm_kernel.print_for_con('Moving '+dst+' to '+src+' ...')
01689           dirList=os.listdir(dst)
01690           for fn in dirList:
01691               p1=os.path.join(dst,fn)
01692               r2=shutil.move(p1, src) 
01693 
01694           # removing tmp directory
01695           cm_kernel.print_for_con('Removing '+dst+' ...')
01696           os.rmdir(dst)
01697 
01698           # removing tmp directory
01699           cm_kernel.print_for_con('Entry successfully repaired!')
01700 
01701           r={'cm_return':0}
01702 
01703     return r
01704 
01705 # ============================================================================
01706 def search(i):
01707 
01708     """
01709     Search
01710 
01711     Input:  {
01712               (repo_selection)        - list of repo UOA to prune search
01713               (module_selection)      - list of module UOA to prune search
01714 
01715               (key_X)                 - key to search (if use_flat_array=='yes', key should be in "flat array" format)
01716               (value_X)               - value to search (find this occurance in the string)
01717 
01718               (cm_es_string)          - ElasticSearch string
01719 
01720               (use_internal_search)   - if 'yes', do not use ElasticSearch
01721               (use_flat_array)        - if 'yes', keys should be in "flat array" format 
01722                                           (
01723                                             flat array is needed to access directly any key in dictionary hierarchy
01724 
01725                                             flat array format examples:
01726                                               {"x":{"y":"z"}} - "##x#y"="z"
01727                                               {"x":["y","z"]} - "##x@0"="y", "##x@1"="z"
01728                                           )
01729 
01730               (show_search_progress)  - if 'yes', show search progress
01731 
01732               (timeout)               - timeout in seconds for internal slow search
01733               (strict_match)          - if 'yes', use strict match (in internal search)
01734               
01735             }
01736 
01737     Output: {
01738               cm_return  - return code >0 if error
01739               all        - list with description of entries returned by search
01740                   [
01741                     {
01742                       cm_repo_uoa           - Found entry's repository UOA (UID or alias)
01743                       cm_repo_uid           - Found entry's repository UID
01744                       cm_module_uoa         - Found entry's module UOA (UID or alias)
01745                       cm_module_uid         - Found entry's module UID
01746                       cm_data_uoa           - Found entry's UOA (UID or alias)
01747                       cm_data_uid           - Found entry's UID
01748                       (cm_display_as_alias) - Fodun entry's user-friendly alias for printing
01749                     }
01750                     ...
01751                   ]
01752             }
01753     """
01754 
01755     use_indexing=False
01756     if i.get('use_internal_search','')!='yes' and \
01757        cm_kernel.ini['dcfg'].get('use_indexing','')=='yes': use_indexing=True
01758 
01759     if i.get('cm_console','')=='web':
01760        # Check styles, etc
01761        if 'cfg' in cm_kernel.ini['web_style']: web=cm_kernel.ini['web_style']['cfg']
01762        else:
01763           return {'cm_return':1, 'cm_error':'web style is not defined'}
01764 
01765        cm_kernel.print_for_con('<B>Search:</B><br>')
01766 
01767        if not use_indexing:
01768           cm_kernel.print_for_con('<i><small>Warning: indexing is turned off - therefore this search is very slow</small></i><br>')
01769 
01770     ######################################################################
01771     rr={'cm_return':0}
01772 
01773     if i.get('cm_console','')=='web' and ('cm_subaction_search_submit' not in i):
01774        cm_kernel.print_for_web('<FORM ACTION="'+web['http_prefix']+'cm_menu=search" METHOD="POST">')
01775 
01776        # ************************** Keywords **************************
01777        if use_indexing:
01778           cm_kernel.print_for_con(web['table_init']+'<tr>')
01779           cm_kernel.print_for_web('<td align="center"><small><b>Search string</b> <i>(elastic search format: image, "GCC 4.7.1", etc):</i></small></td>')
01780 
01781           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01782               'cm_action':'convert_field_to_html',
01783               'cm_value':'',
01784               'cm_key':'cm_es_string',
01785               'cm_mode':'add',
01786               'cm_data_desc':{"type":"text"}}
01787           r1=cm_kernel.access(ii)
01788           if r1['cm_return']>0: 
01789              v='<B>cM error:</b> '+r1['cm_error']
01790           else:
01791              v=r1['cm_value_html']
01792           cm_kernel.print_for_web('<td>'+v+'</td></tr></table>')
01793 
01794        cm_kernel.print_for_web(web['table_init']+'<tr>')
01795        cm_kernel.print_for_con('<td colspan="2" align="center"><small><b><i>Enter key (not obligtory) and value</i></b></small></td></tr>')
01796 
01797        cm_kernel.print_for_con('<tr><td><small><b>Json key:</b></small></td>')
01798        cm_kernel.print_for_con('<td><small><b>Value:</b></small></td></tr>')
01799 
01800        for u in range(0, 6):
01801            ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01802                'cm_action':'convert_field_to_html',
01803                'cm_value':'',
01804                'cm_key':'key_'+str(u),
01805                'cm_mode':'add',
01806                'cm_data_desc':{"type":"text"}}
01807            r1=cm_kernel.access(ii)
01808            if r1['cm_return']>0: 
01809               v='<B>cM error:</b> '+r1['cm_error']
01810            else:
01811               v=r1['cm_value_html']
01812            cm_kernel.print_for_web('<TR><TD>'+v+'</TD>')
01813 
01814            ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01815                'cm_action':'convert_field_to_html',
01816                'cm_value':'',
01817                'cm_key':'value_'+str(u),
01818                'cm_mode':'add',
01819                'cm_data_desc':{"type":"text"}}
01820            r1=cm_kernel.access(ii)
01821            if r1['cm_return']>0: 
01822               v='<B>cM error:</b> '+r1['cm_error']
01823            else:
01824               v=r1['cm_value_html']
01825            cm_kernel.print_for_web('<TD>'+v+'</TD></tr>')
01826 
01827        cm_kernel.print_for_con('</tr></table>')
01828 
01829        cm_kernel.print_for_web(web['table_init']+'<tr>')
01830        cm_kernel.print_for_con('<td colspan="2" align="center"><small><b><i>Prune search</i></b></small></td></tr><tr>')
01831 
01832        # ************************** Select repo **************************
01833        cm_kernel.print_for_con('<td><small><B>Repository:</B></small><BR>')
01834        cm_kernel.print_for_con('<select class="cm-select" size="6" name="repo_selection[]" multiple>')
01835 
01836        r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
01837                            'cm_action':'list'})
01838        if r['cm_return']>0: return r
01839 
01840        found=False
01841        for xx in sorted(r['cm_mixed'], key=lambda k: k['cm_uoa']):
01842            x=xx['cm_uoa'];  xu=xx['cm_uid'];  xa=xx['cm_alias']
01843            cm_kernel.print_for_web('<option value="'+xu+'">'+x+'</option>')
01844        cm_kernel.print_for_con('</select><br></td>')
01845 
01846        # ************************** Select module **************************
01847        cm_kernel.print_for_con('<td><small><B>Module:</B></small><BR>')
01848        cm_kernel.print_for_con('<select class="cm-select" size="6" name="module_selection[]" multiple>')
01849 
01850        r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-module'],
01851                            'cm_action':'list'})
01852        if r['cm_return']>0: return r
01853 
01854        found=False
01855        for xx in sorted(r['cm_mixed'], key=lambda k: k['cm_uoa']):
01856            x=xx['cm_uoa'];  xu=xx['cm_uid'];  xa=xx['cm_alias']
01857            cm_kernel.print_for_web('<option value="'+xu+'">'+x+'</option>')
01858        cm_kernel.print_for_con('</select><br></td>')
01859 
01860        cm_kernel.print_for_con('</tr></table>')
01861 
01862        # ************************** Keywords **************************
01863        cm_kernel.print_for_web(web['table_init']+'<tr>')
01864        cm_kernel.print_for_con('<td align="center"><small><b><i>Misc</i></b></small></td></tr>')
01865 
01866        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
01867            'cm_action':'convert_field_to_html',
01868            'cm_value':'10',
01869            'cm_key':'timeout',
01870            'cm_mode':'update',
01871            'cm_data_desc':{"type":"text"}}
01872        r1=cm_kernel.access(ii)
01873        if r1['cm_return']>0: 
01874           v='<B>cM error:</b> '+r1['cm_error']
01875        else:
01876           v='Search timeout: '+r1['cm_value_html']
01877        cm_kernel.print_for_web('<TR><TD>'+v+'</TD></table>')
01878 
01879        cm_kernel.print_for_con('<input type="submit" class="cm-button" name="cm_subaction_search_submit" value="Find">')
01880        cm_kernel.print_for_web('<input type="button" onclick="location.href=\''+web['http_prefix']+'cm_menu=search\'" value="Clear form">')
01881        cm_kernel.print_for_con('</FORM>')
01882 
01883     ######################################################################
01884     else:
01885        # Init some variables
01886        all=[]
01887        timeout=False
01888 
01889        if use_indexing:
01890           es_string=''
01891           if 'cm_es_string' in i: es_string=i['cm_es_string']
01892           
01893           if 'repo_selection' in i and len(i['repo_selection'])>0:
01894              if es_string!='': es_string+=' AND '
01895              es_string+=' ('
01896              first=True
01897              for x in i['repo_selection']:
01898                  if first: first=False
01899                  else: es_string+=' OR '
01900                  es_string+='(cm_repo_uid:"'+x+'") OR (cm_repo_uoa:"'+x+'")'
01901              es_string+=')'
01902 
01903           if 'module_selection' in i and len(i['module_selection'])>0:
01904              if es_string!='': es_string+=' AND '
01905              es_string+='('
01906              first=True
01907              for x in i['module_selection']:
01908                  if first: first=False
01909                  else: es_string+=' OR '
01910                  es_string+='(cm_module_uid:"'+x+'") OR (cm_module_uoa:"'+x+'")'
01911              es_string+=')'
01912 
01913           # Check search keys
01914           first=True
01915           for u in range(0,100):
01916               k='key_'+str(u)
01917               v='value_'+str(u)
01918 
01919               if i.get(k,'')!='' or i.get(v,'')!='':
01920                  if first: 
01921                     first=False
01922                     if es_string=='': es_string+='('
01923                     else: es_string+=' AND ('
01924                  else: 
01925                     es_string+=' AND '
01926 
01927               o='"'
01928               if i.get(k,'')!='':
01929                  v1='""'
01930                  if i.get(v,'')!='': v1=i[v]
01931                  if '*' in v1 or '?' in v1: o=''
01932                  es_string+=i[k]+':'+o+v1+o
01933               elif i.get(v,'')!='':
01934                  v1=i[v]
01935                  if '*' in v1 or '?' in v1: o=''
01936                  es_string+=o+v1+o
01937 
01938           if not first:
01939              es_string+=')'
01940 
01941 #          check=[]
01942 #          if ('module_selection' in i and len(i['module_selection'])>0) and \
01943 #             ('repo_selection' not in i or len(i['repo_selection']==0)):
01944 #             for x in i['module_selection']:
01945 #                 check.append({'cm_module_uid':x})
01946 #
01947 #          elif ('repo_selection' in i and len(i['repo_selection'])>0) and \
01948 #             ('module_selection' not in i or len(i['module_selection']==0)):
01949 #             for y in i['repo_selection']:
01950 #                 check.append({'cm_repo_uid':y})
01951 #           
01952 #          elif ('repo_selection' in i and len(i['repo_selection'])>0) and \
01953 #             ('module_selection' in i and len(i['module_selection']>0)):
01954 #             for y in i['repo_selection']:
01955 #                 for x in i['module_selection']:
01956 #                     check.append({'cm_repo_uid':y, 
01957 #                                   'cm_module_uid':x})
01958 #          else:
01959 #             check.append({})
01960 
01961           # Call index search
01962           if es_string=='':
01963              es_string='*'
01964 
01965           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
01966               'cm_action':'search',
01967               'cm_es_string':es_string}
01968 
01969           if i.get('cm_console','')=='web':
01970              cm_kernel.print_for_web('<BR><small><b>Query string:</b><BR><i>'+ii['cm_es_string']+'</i></small><BR><BR>')
01971           r=cm_kernel.access(ii)
01972           if r['cm_return']>0: return r
01973           all=r['cm_array']
01974 
01975        else:
01976           # Check search keys
01977           s=[]
01978           for u in range(0,100):
01979               k='key_'+str(u)
01980               v='value_'+str(u)
01981 
01982               if k in i and i[k]!='':
01983                  v1=''
01984                  if v in i and i[v]!='': v1=i[v]
01985                  s.append({"key":i[k], "value":v1})
01986               elif v in i and i[v]!='':
01987                  s.append({"value":i[v]})
01988 
01989           # Start timer
01990           t0=time.time()
01991           td=10
01992           if i.get('timeout','')!='': td=int(i['timeout'])
01993           if td<1 or td>1000: td=1000
01994 
01995           # Search through repositories
01996           r1=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
01997                                'cm_action':'list'})
01998           if r1['cm_return']>0: return r1
01999 
02000           for repo1 in sorted(r1['cm_mixed'], key=lambda k: k['cm_uoa']):
02001               # Check timeout
02002               if (time.time()-t0)>td: timeout=True; break
02003 
02004               repo_uoa=repo1['cm_uoa']
02005               repo_uid=repo1['cm_uid']
02006               if 'repo_selection' not in i or len(i['repo_selection'])==0 or repo_uid in i['repo_selection'] or repo_uoa in i['repo_selection']:
02007                  # Load repo to check if should ignore external repos for search
02008                  r9=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
02009                                       'cm_data_uoa':repo_uoa,
02010                                       'cm_action':'load'})
02011                  if r9['cm_return']>0: return r9
02012                  r9d=r9['cm_data_obj']['cfg']
02013 
02014                  if r9d.get('exclude_from_search','')!='yes':
02015 
02016                     # Search through available modules
02017                     r=cm_kernel.access({'cm_run_module_uoa':ini['cm_module_uid'],
02018                                         'cm_action':'list',
02019                                         'cm_repo_uoa':repo_uoa,
02020                                         'cm_only_available_modules':'yes'})
02021                     if r['cm_return']>0: return r
02022 
02023                     for module1 in sorted(r['cm_mixed'], key=lambda k: k['cm_uoa']):
02024                         # Check timeout
02025                         if (time.time()-t0)>td: timeout=True; break
02026 
02027                         module_uoa=module1['cm_uoa']
02028                         module_uid=module1['cm_uid']
02029 
02030                         if 'module_selection' not in i or len(i['module_selection'])==0 or module_uid in i['module_selection'] or module_uoa in i['module_selection']:
02031 
02032                            # Load module
02033                            r8=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-module'],
02034                                                 'cm_data_uoa':module_uoa,
02035                                                 'cm_action':'load'})
02036                            if r8['cm_return']>0: return r8
02037                            r8d=r8['cm_data_obj']['cfg']
02038 
02039                            # List data
02040                            r1=cm_kernel.access({'cm_run_module_uoa':module_uoa,
02041                                                 'cm_repo_uoa':repo_uoa,
02042                                                 'cm_action':'list'})
02043                            if r1['cm_return']>0: return r1
02044                            for data1 in sorted(r1['cm_mixed'], key=lambda k: k['cm_uoa']):
02045                                # Check timeout
02046                                if (time.time()-t0)>td: timeout=True; break
02047 
02048                                data_uoa=data1['cm_uoa']
02049                                data_uid=data1['cm_uid']
02050 
02051                                if i.get('show_search_progress', '')=='yes':
02052                                   cm_kernel.print_for_con('Searching '+repo_uoa+':'+module_uoa+':'+data_uoa+' (elapsed time = '+("%.1f" % (time.time()-t0))+' sec.)')
02053 
02054                                # Load data
02055                                r2=cm_kernel.access({'cm_run_module_uoa':module_uoa,
02056                                                     'cm_repo_uoa':repo_uoa,
02057                                                     'cm_data_uoa':data_uoa,
02058                                                     'cm_action':'load'})
02059                                if r2['cm_return']>0: return r2
02060 
02061                                d=r2['cm_data_obj']['cfg']
02062 
02063                                display_as_alias=d.get('cm_display_as_alias','')
02064 
02065                                found=True
02066                                if len(s)>0:
02067                                   for ss in s:
02068                                       r3=find_key_value_in_array({'cm_array':d, 'cm_search': ss, \
02069                                                                   'use_flat_array':i.get('use_flat_array',''),
02070                                                                   'strict_match':i.get('strict_match','')})
02071                                       if r3['cm_return']>0: return r3
02072                                       if not r3['cm_found']: found=False; break
02073 
02074                                if found:
02075                                   # Adding to the list
02076                                   ii={'cm_repo_uoa':repo_uoa,
02077                                       'cm_repo_uid':repo_uid,
02078                                       'cm_module_uoa':module_uoa,
02079                                       'cm_module_uid':module_uid,
02080                                       'cm_data_uoa':data_uoa,
02081                                       'cm_data_uid':data_uid}
02082                                   if display_as_alias!='': ii['cm_display_as_alias']=display_as_alias
02083                                   if r9d.get('cm_display_as_alias','')!='': ii['cm_repo_display_as_alias']=r9d['cm_display_as_alias']
02084                                   if r8d.get('cm_display_as_alias','')!='': ii['cm_module_display_as_alias']=r8d['cm_display_as_alias']
02085 
02086                                   all.append(ii)
02087 
02088                                   if i.get('show_search_progress', '')=='yes':
02089                                      cm_kernel.print_for_con('  Found!')
02090 
02091        # Show results
02092        if i.get('cm_console','')=='web':
02093           cm_kernel.print_for_web(web['table_init'])
02094 
02095           cm_kernel.print_for_con('<tr>')
02096           cm_kernel.print_for_con('<td><b>#</b></td>')
02097           cm_kernel.print_for_con('<td><b>Repository:</b></td>')
02098           cm_kernel.print_for_con('<td><b>Module:</b></td>')
02099           cm_kernel.print_for_con('<td><b>Data:</b></td>')
02100           cm_kernel.print_for_con('</tr>')
02101 
02102           count=0
02103           for x in all:
02104               repo_uoa=x.get('cm_repo_uoa','')
02105               repo_print=repo_uoa
02106               if x.get('cm_repo_display_as_alias','')!='': repo_print=x['cm_repo_display_as_alias']
02107               repo_print=repo_print[0].upper()+repo_print[1:]
02108 
02109               module_uoa=x.get('cm_module_uoa','')
02110               module_print=module_uoa
02111               if x.get('cm_module_display_as_alias','')!='': module_print=x['cm_module_display_as_alias']
02112               module_print=module_print[0].upper()+module_print[1:]
02113 
02114               data_uoa=x.get('cm_data_uoa','')
02115               data_print=data_uoa
02116               if x.get('cm_display_as_alias','')!='': data_print=x['cm_display_as_alias']
02117               data_print=data_print[0].upper()+data_print[1:]
02118 
02119               cid=repo_uoa
02120               if cid!='': cid+=':'
02121               cid+=module_uoa+':'+data_uoa
02122 
02123               count+=1
02124 
02125               cm_kernel.print_for_con('<tr>')
02126               cm_kernel.print_for_web('<td><i>'+str(count)+'</i></td>')
02127               cm_kernel.print_for_web('<td>'+repo_print+'</td>')
02128               cm_kernel.print_for_web('<td><i>'+module_print+'</i></td>')
02129 #              cm_kernel.print_for_web('<td><a href="'+web['http_prefix']+'cm_menu='+web['cm_menu_browse']+'&cm_subaction_view&browse_cid='+cid+'" target="_blank">'+data_print+'</a></td>')
02130               cm_kernel.print_for_web('<td><a href="'+web['http_prefix']+'view_cid='+cid+'" target="_blank">'+data_print+'</a></td>')
02131 
02132               cm_kernel.print_for_con('</tr>')
02133 
02134           cm_kernel.print_for_con('</table>')
02135 
02136           if timeout:
02137              cm_kernel.print_for_con('<BR>Timed out ...<BR>')
02138        elif i.get('cm_console','')=='txt':
02139             for x in all:
02140                 cid=''
02141                 if x.get('cm_repo_uoa','')!='': cid+=x['cm_repo_uoa']+':'
02142                 cid+=x['cm_module_uoa']+':'+x['cm_data_uoa']
02143 
02144                 cid1=''
02145                 if x.get('cm_repo_uid','')!='': cid1+=x['cm_repo_uid']+':'
02146                 cid1+=x['cm_module_uid']+':'+x['cm_data_uid']
02147 
02148 #                y=cid
02149 #                for i in range(len(y),60): y+=' '
02150 #                y+='  '+cid1
02151 
02152                 cm_kernel.print_for_web(cid1+'   '+cid)
02153 
02154        rr.update({'all':all})
02155 
02156     return rr
02157 
02158 # ============================================================================
02159 def find_key_value_in_array(i):
02160 
02161     """
02162     Find key/value pair in array 
02163 
02164     Input:  {
02165               cm_array          - array
02166               cm_search         - {"key": key, "value": value} or {"value":value}
02167               (use_flat_array)  - if 'yes', keys should be in "flat array" format (##x#y ...)
02168               (strict_match)    - if 'yes', make exact comparison of values
02169             }
02170 
02171     Output: {
02172               cm_return  - return code >0 if error
02173               cm_found   - True if found
02174             }
02175     """
02176 
02177     found=False
02178 
02179     a=i['cm_array']
02180     s=i['cm_search']
02181 
02182     k=''
02183     if 'key' in s: k=s['key']
02184     v=s['value']
02185 
02186     if k=='' and v=='': 
02187        found=True
02188     else:
02189        if i.get('use_flat_array','')=='yes' and k!='':
02190           rg=cm_kernel.get_value_by_flattened_key({'cm_array':a, 'cm_key':k})
02191           if rg['cm_return']>0: return rg
02192           vv=rg['cm_value']
02193           if v=='' or v==vv or (i.get('strict_match','')!='yes' and vv!=None and string.find(str(vv).lower(), v.lower())!=-1): 
02194              found=True
02195        else:
02196           for x in a:
02197               if type(a) is dict: y=a[x]
02198               elif type(a) is list: y=x
02199 
02200               if isinstance(y, str) or isinstance(y,unicode):
02201                  if k=='' or (type(a) is dict and x==k):
02202                     if string.find(y.lower(), v.lower())!=-1: 
02203                        found=True
02204                        break
02205               elif type(y) is dict or type(y) is list:
02206                  r=find_key_value_in_array({'cm_array':y, 'cm_search':s, 'use_flat_array':i.get('use_flat_array','')})
02207                  if r['cm_return']>0: return r
02208                  elif r['cm_found']: found=True; break
02209 
02210     return {'cm_return':0, 'cm_found':found}
02211 
02212 # ============================================================================
02213 def convert_str_to_sha1(i):
02214 
02215     """
02216     Convert string to sha1
02217 
02218     Input:  {
02219               cm_string       - string
02220               (cm_console)    - by default, do not output anything except errors
02221                                 if 'txt' then output as plain text
02222                                 if 'web' then output for web (html, image, etc)
02223                                 if 'json' then output as json
02224             }
02225 
02226     Output: {
02227               cm_return             - return code >0 if not authentificated
02228               cm_string_sha1        - password in SHA1 (digest) (only if console is not json, otherwise doens't work)
02229               cm_string_sha1_hex    - password in SHA1 (digest in hex)
02230               cm_string_sha1_base64 - BASE64 (SHA1 digest) - compatible with htpasswd format
02231             }
02232     """
02233 
02234     if 'cm_string' not in i: 
02235        return {'cm_return':1, 'cm_error':'"cm_string" is not set'}
02236 
02237     r=cm_kernel.convert_str_to_sha1(i)
02238 
02239     if i.get('cm_console','')=='json':
02240        del(r['cm_string_sha1'])
02241 
02242 
02243     if i.get('cm_console','')=='txt':
02244        cm_kernel.print_for_con("SHA1_HEX="+r['cm_string_sha1_hex'])
02245        cm_kernel.print_for_con("SHA1_BASE64="+r['cm_string_sha1_base64'])
02246 
02247     return r
02248 
02249 # ============================================================================
02250 def configure(i):
02251 
02252     """
02253     Configure default params
02254 
02255     Input:  {
02256             }
02257 
02258     Output: {
02259               cm_return       - return code >0 if not authentificated
02260             }
02261     """
02262 
02263     line='******************************************************************************'
02264 
02265     cm_kernel.print_for_con('')
02266     cm_kernel.print_for_con('Welcome to Collective Mind framework')
02267 
02268     cm_kernel.print_for_con('')
02269     cm_kernel.print_for_con('Configuring major cM parameters through CMD')
02270     cm_kernel.print_for_con('  Notes:' )
02271     cm_kernel.print_for_con('')
02272     cm_kernel.print_for_con('    * After first use of this configurator, you can use cM web front-end to configure advanced cM settings!')
02273     cm_kernel.print_for_con('    * You can re-run this configuration at any time without destroying your current config!')
02274 
02275     cm_kernel.print_for_con('')
02276     cm_kernel.print_for_con(line)
02277 
02278     cm_kernel.print_for_con('NOTE:' )
02279     cm_kernel.print_for_con('  If you want to use web-server and indexing server, you should start them now in another terminal')
02280     cm_kernel.print_for_con('')
02281     cm_kernel.print_for_con('You can start internal cM web server using:')
02282     cm_kernel.print_for_con('')
02283     cm_kernel.print_for_con('   * Linux:   invoke "cm web server" and put it to background using Ctrl-Z and "bg"')
02284     cm_kernel.print_for_con('   * Windows: invoke "cm_start_web.bat"')
02285     cm_kernel.print_for_con('')
02286     cm_kernel.print_for_con('You can start cM indexing server (that uses external Elastic Search including in cM):')
02287     cm_kernel.print_for_con('')
02288     cm_kernel.print_for_con('   * Linux:   invoke "cm index server" and put it to background using Ctrl-Z and "bg"')
02289     cm_kernel.print_for_con('   * Windows: invoke "cm_start_indexing.bat"')
02290     cm_kernel.print_for_con('')
02291     cm_kernel.print_for_con('   IF YOU START INDEXING SERVER FOR THE FIRST TIME, DON\'T FORGET TO INDEX ALL ENTRIES USING')
02292     cm_kernel.print_for_con('      cm index all')
02293     cm_kernel.print_for_con('')
02294     cm_kernel.print_for_con('You can speed up indexing if you install CURL on Linux (it is already pre-packaged with cM on Windows)')
02295 
02296     cm_kernel.print_for_con('')
02297     var=raw_input('Press enter to continue: ')
02298 
02299     # Get latest installation notes
02300     r=cm_kernel.get_cm_version({})
02301     if r['cm_return']>0: return r
02302 
02303     u=cm_kernel.ini['dcfg'].get('url_engine_version_update_check','')
02304     if u!='':
02305        cm_kernel.print_for_con(line)
02306        cm_kernel.print_for_con('We recommend to download latest cM news/notes from c-mind.org')
02307 
02308        while True:
02309           cm_kernel.print_for_con('')
02310           var=raw_input('Would you like to read notes (YES or no): ')
02311           var=var.lower()
02312           if var=='no': break
02313           elif var=='yes' or var=='':
02314              cm_kernel.print_for_con('')
02315 
02316              lnk=u+r['cm_string']+'_notes.html'
02317 
02318              page=''
02319              try:
02320                 res=urllib2.urlopen(lnk)
02321                 page=res.read()
02322              except urllib2.HTTPError as e:
02323                 cm_kernel.print_for_con('Problem accessing c-mind.org ('+format(e)+')!')
02324              except urllib2.URLError as e:
02325                 cm_kernel.print_for_con('Problem accessing c-mind.org ('+format(e)+')!')
02326 
02327              if page!='':
02328                 s1='<!-- START TEXT -->'
02329                 i1=page.find(s1)
02330                 if i1>0:
02331                    i2=page.find('<!-- STOP TEXT -->')
02332                    if i2>0:
02333                       text=page[i1+len(s1):i2].strip()
02334                  
02335                       cm_kernel.print_for_con('Latest news/notes from c-mind.org:')
02336                       cm_kernel.print_for_con('')
02337                       cm_kernel.print_for_con(text)
02338 
02339              cm_kernel.print_for_con('')
02340              var=raw_input('Press enter to continue: ')
02341 
02342              break
02343   
02344     # Loading clean cM configuration
02345     cm_kernel.print_for_con(line)
02346     cm_kernel.print_for_con('Loading current configuration ...')
02347     pcfg=cm_kernel.ini['pcfg']
02348 
02349     ra=cm_kernel.load_json_file({'cm_filename':pcfg})
02350     if ra['cm_return']>0: return ra
02351     d=ra['cm_array']
02352     
02353     # Checking if local kernel configuration exists (i.e. not the first run)
02354     if cm_kernel.env_cm_cfg not in os.environ.keys() or os.environ[cm_kernel.env_cm_cfg]=='':
02355        rx=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-kernel'],
02356                             'cm_data_uoa':cm_kernel.var_cm_cfg_local,
02357                             'cm_action':'load'})
02358        if rx['cm_return']==16:
02359           cm_kernel.print_for_con('')
02360           cm_kernel.print_for_con('It seems that you are setting configuration for the first time')
02361           cm_kernel.print_for_con('  (local kernel configuration doesn\'t exist)')
02362           cm_kernel.print_for_con('')
02363           cm_kernel.print_for_con('We strongly suggest you to copy "default" kernel configuration to "local" one')
02364           cm_kernel.print_for_con('')
02365 
02366           while True:
02367              var=raw_input('Would you like to perform this operation (YES or no): ')
02368              var=var.lower()
02369              if var=='no': break
02370              elif var=='yes' or var=='':
02371                 cm_kernel.print_for_con('')
02372                 cm_kernel.print_for_con('Adding "local" kernel entry ...')
02373 
02374                 ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-kernel'],
02375                     'cm_data_uoa':cm_kernel.var_cm_cfg_local,
02376                     'cm_action':'add',
02377                     'cm_array':d}
02378                 r=cm_kernel.access(ii)
02379                 if r['cm_return']>0: return r
02380 
02381                 pcfg=os.path.join(r['cm_path'], d['dcm'], d['fconfig'])
02382                 
02383                 break
02384                 
02385        elif rx['cm_return']>0: return rx
02386        else:
02387           pcfg=os.path.join(rx['cm_path'], d['dcm'], d['fconfig'])
02388 
02389     # Detecting host OS ****************************************************************
02390     cm_kernel.print_for_con(line)
02391     cm_kernel.print_for_con('Trying to detect host OS ...')
02392 
02393     cm_kernel.print_for_con('')
02394     r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['os'],
02395                         'cm_action':'detect_host_family',
02396                         'cm_console':'txt'})
02397     if r['cm_return']>0: return r
02398 
02399     cm_os_uoa_list=r['cm_os_uoa_list']
02400 
02401     # Check default OS
02402     if 'cm_default_os_uoa' in d and d['cm_default_os_uoa']!='':
02403        ry=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['os'],
02404                             'cm_action':'load',
02405                             'cm_data_uoa':d['cm_default_os_uoa']})
02406        if ry['cm_return']==0:
02407           cm_kernel.print_for_con('')
02408           cm_kernel.print_for_con('The following OS is currently set in the cM configuration: '+ry['cm_alias']+' ('+ry['cm_uid']+')')
02409 
02410     cm_kernel.print_for_con('')
02411     while True:
02412           var=raw_input('Enter most close OS to your host OS from the above list (or press Enter to keep current setting): ')
02413  
02414           if var=='': break
02415           else:
02416              rx=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['os'],
02417                                   'cm_action':'load',
02418                                   'cm_data_uoa':var})
02419              if rx['cm_return']==0: break
02420 
02421              cm_kernel.print_for_con('')
02422              cm_kernel.print_for_con('Problem loading selected OS ('+rx['cm_error']+') ...')
02423 
02424              cm_kernel.print_for_con('')
02425              
02426     if var=='':
02427        cm_kernel.print_for_con('')
02428        cm_kernel.print_for_con('Keeping current setting ...')
02429     else:
02430        cm_kernel.print_for_con('')
02431        cm_kernel.print_for_con('Updating configuration file ...')
02432 
02433        d['cm_default_os_uoa']=rx['cm_uid']
02434 
02435        rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
02436        if rz['cm_return']>0: return rz
02437 
02438     # Configure user (remote and local) ***********
02439     cmind_repo=ini['cfg']['cm_cmind_repo_uoa']
02440 
02441     cm_kernel.print_for_con(line)
02442     cm_kernel.print_for_con('Configuring unique cM username (local and public cM usernames are the same):')
02443     cm_kernel.print_for_con('')
02444     cm_kernel.print_for_con('  IT IS AN EXTREMELY IMPORTANT STEP to be able to access all public collective c-mind.org data,')
02445     cm_kernel.print_for_con('  online characterization, tuning and prediction functionality, etc!')
02446 
02447     cm_default_user_uoa=d.get('cm_default_user_uoa','')
02448 
02449     if cm_default_user_uoa!='' and cm_default_user_uoa!=ini['cfg']['cm_default_user_uoa']:
02450        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-user'],
02451            'cm_action':'load',
02452            'cm_data_uoa':cm_default_user_uoa}
02453        rz=cm_kernel.access(ii)
02454        if rz['cm_return']>0: return rz
02455 
02456        cm_kernel.print_for_con('')
02457        cm_kernel.print_for_con('Default user is already set up: '+rz['cm_uoa']+' ('+rz['cm_uid']+')')
02458 
02459        while True:
02460           cm_kernel.print_for_con('')
02461           var=raw_input('Would you like to change it (yes/NO)? ')
02462           var=var.lower()
02463           if var=='' or var=='yes' or var=='no': break
02464 
02465     if var=='yes':
02466        cm_default_user_uoa=''
02467 
02468     # Loading cmind repo
02469     cm_kernel.print_for_con('')
02470     cm_kernel.print_for_con('Loading c-mind.org repository ...')
02471 
02472     ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
02473         'cm_action':'load',
02474         'cm_data_uoa':cmind_repo}
02475     rz=cm_kernel.access(ii)
02476     if rz['cm_return']>0: return rz
02477     dq=rz['cm_data_obj']['cfg']
02478     cmind_url=dq.get('url','')
02479 
02480     if cm_default_user_uoa=='' or cm_default_user_uoa==ini['cfg']['cm_default_user_uoa']:
02481        # Checking if already pre-registered
02482        while True:
02483           cm_kernel.print_for_con('')
02484           var=raw_input('Do you already have local username (if yes, you can simply register it as default user) (yes/NO)? ')
02485           var=var.lower()
02486           if var=='' or var=='yes' or var=='no': break
02487 
02488        if var=='yes':
02489           cm_kernel.print_for_con('')
02490           cm_default_user_uoa=raw_input('Enter existing username: ')
02491 
02492           # Attempt to load user
02493           cm_kernel.print_for_con('')
02494           cm_kernel.print_for_con('Trying to load local user ...')
02495 
02496           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-user'],
02497               'cm_action':'load',
02498               'cm_data_uoa':cm_default_user_uoa}
02499           rz=cm_kernel.access(ii)
02500           if rz['cm_return']>0: 
02501              cm_kernel.print_for_con('')
02502              cm_kernel.print_for_con('  Local user not found')
02503              cm_default_user_uoa=''
02504           else:
02505              dq=rz['cm_data_obj']['cfg']
02506 
02507              cm_kernel.print_for_con('')
02508              cm_kernel.print_for_con('  Testing access to public c-mind.org server')
02509 
02510              cm_kernel.print_for_con('')
02511              username=rz['cm_uoa']
02512              password=getpass.getpass('  Enter password: ')
02513              password=password.strip()
02514 
02515              success=False
02516 
02517              cm_kernel.print_for_con('')
02518              ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
02519                  'cm_action':'test',
02520                  'test_repo_uoa':cmind_repo,
02521                  'cm_remote_user_uoa':username,
02522                  'cm_remote_user_password':password}
02523              rz=cm_kernel.access(ii)
02524              if rz['cm_return']>0: 
02525                 cm_kernel.print_for_con('  Access to c-mind.org public repository failed:')
02526                 cm_kernel.print_for_con('')
02527                 cm_kernel.print_for_con('  Server returned error: '+rz['cm_error'])
02528 
02529                 cm_default_user_uoa=''
02530 
02531                 cm_kernel.print_for_con('')
02532                 cm_kernel.print_for_con('Please, register another user or check password!')
02533 
02534              else:
02535                 success=True
02536                 cm_kernel.print_for_con('  SUCCESS!')
02537 
02538     # No local user. Check if registered at c-mind
02539     if cm_default_user_uoa=='' or cm_default_user_uoa==ini['cfg']['cm_default_user_uoa']:
02540        while True:
02541           cm_kernel.print_for_con('')
02542           var=raw_input('Are you already registered at '+cmind_url+' (yes/NO)? ')
02543           var=var.lower()
02544           if var=='' or var=='yes' or var=='no': break
02545 
02546        if var=='yes':
02547           cm_kernel.print_for_con('')
02548           cm_kernel.print_for_con('  Testing access to public c-mind.org server')
02549 
02550           cm_kernel.print_for_con('')
02551           username=             raw_input('   Enter username: ')
02552           password=       getpass.getpass('   Enter password: ')
02553           password=password.strip()
02554           password_repeat=getpass.getpass('  Repeat password: ')
02555           password_repeat=password_repeat.strip()
02556           name=                 raw_input('  Enter real name: ')
02557 
02558           success=False
02559 
02560           cm_kernel.print_for_con('')
02561           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
02562               'cm_action':'test',
02563               'test_repo_uoa':cmind_repo,
02564               'cm_remote_user_uoa':username,
02565               'cm_remote_user_password':password_repeat}
02566           rz=cm_kernel.access(ii)
02567           if rz['cm_return']>0: 
02568              cm_kernel.print_for_con('  Access to c-mind.org public repository failed:')
02569              cm_kernel.print_for_con('')
02570              cm_kernel.print_for_con('  Server returned error: '+rz['cm_error'])
02571 
02572           else:
02573              success=True
02574              cm_kernel.print_for_con('  SUCCESS!')
02575 
02576              cm_kernel.print_for_con('')
02577              cm_kernel.print_for_con('Adding this user to local repository:')
02578              cm_kernel.print_for_con('')
02579 
02580              ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-user'],
02581                  'cm_action':'add',
02582                  'cm_array':{'cm_username':username,
02583                              'cm_user_password':password,
02584                              'cm_user_password_repeat':password_repeat,
02585                              'name':name}}
02586              rz=cm_kernel.access(ii)
02587              if rz['cm_return']>0: 
02588                 cm_kernel.print_for_con('  Problem adding user: '+rz['cm_error'])
02589              else:
02590                 cm_default_user_uoa=rz['cm_uoa']
02591 
02592     if cm_default_user_uoa=='' or cm_default_user_uoa==ini['cfg']['cm_default_user_uoa']:
02593        # Not registered at c-mind. Try to add new user
02594        while True:
02595           cm_kernel.print_for_con('')
02596           var=raw_input('Would you like to add new user and register at c-mind.org (STRONGLY RECOMMENDED) (YES/no)? ')
02597           var=var.lower()
02598           if var=='' or var=='yes' or var=='no': break
02599 
02600        if var=='yes' or var=='':
02601           cm_kernel.print_for_con('')
02602           cm_kernel.print_for_con('Adding cM user:')
02603 
02604           cm_kernel.print_for_con('')
02605           username=             raw_input('   Enter username: ')
02606           password=       getpass.getpass('   Enter password: ')
02607           password_repeat=getpass.getpass('  Repeat password: ')
02608           name=                 raw_input('  Enter real name: ')
02609 
02610           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-user'],
02611               'cm_action':'add',
02612               'cm_array':{'cm_username':username,
02613                           'cm_user_password':password,
02614                              'cm_user_password_repeat':password_repeat}}
02615           rz=cm_kernel.access(ii)
02616           if rz['cm_return']>0: return rz
02617 
02618           cm_default_user_uoa=rz['cm_uoa']
02619 
02620           cm_kernel.print_for_con('')
02621           cm_kernel.print_for_con('Registering user at c-mind.org:')
02622           # Trying to register at c-mind.org ...
02623           rz=cm_kernel.remote_access({'cm_remote_url':cmind_url,
02624                                       'cm_web_module_uoa':'user',
02625                                       'cm_web_action':'add',
02626                                       'cm_array':{'cm_username':username,
02627                                                   'cm_user_password':password,
02628                                                   'cm_user_password_repeat':password_repeat,
02629                                                   'name':name}})
02630           if rz['cm_return']>0: return rz
02631 
02632           cm_kernel.print_for_con('')
02633           cm_kernel.print_for_con('  Testing access to public c-mind.org server')
02634 
02635           cm_kernel.print_for_con('')
02636           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
02637               'cm_action':'test',
02638               'test_repo_uoa':cmind_repo,
02639               'cm_remote_user_uoa':username,
02640               'cm_remote_user_password':password_repeat}
02641           rz=cm_kernel.access(ii)
02642           if rz['cm_return']>0: 
02643              cm_kernel.print_for_con('  Access to c-mind.org public repository failed:')
02644              cm_kernel.print_for_con('')
02645              cm_kernel.print_for_con('  Server returned error: '+rz['cm_error'])
02646 
02647           else:
02648              cm_kernel.print_for_con('  SUCCESS!')
02649 
02650     # If added new user, try to make it default
02651     if cm_default_user_uoa!='':
02652        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-user'],
02653            'cm_action':'load',
02654            'cm_data_uoa':cm_default_user_uoa}
02655        rz=cm_kernel.access(ii)
02656        if rz['cm_return']>0: return rz
02657 
02658        if rz['cm_uoa']!=d['cm_default_user_uoa'] and rz['cm_uid']!=d['cm_default_user_uoa']:
02659           cm_kernel.print_for_con('')
02660           cm_kernel.print_for_con('Making local user default:')
02661 
02662           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-user'],
02663               'cm_action':'load',
02664               'cm_data_uoa':cm_default_user_uoa}
02665           rz=cm_kernel.access(ii)
02666           if rz['cm_return']>0: return rz
02667 
02668           d['cm_default_user_uoa']=rz['cm_uoa']
02669 
02670           cm_kernel.print_for_con('')
02671           cm_kernel.print_for_con('Adding cM user to admins:')
02672 
02673           if 'admin_users' not in d: d['admin_users']=[]
02674           admins=d.get('admin_users',[])
02675           if rz['cm_uid'] not in admins:
02676              admins.append(rz['cm_uid'])
02677           if rz['cm_uoa'] not in admins:
02678              admins.append(rz['cm_uoa'])
02679 
02680           rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
02681           if rz['cm_return']>0: return rz
02682 
02683           cm_kernel.print_for_con('')
02684           cm_kernel.print_for_con('Configuration has been updated successfully!')
02685 
02686     # Force user login **********
02687 
02688     cm_kernel.print_for_con(line)
02689     cm_kernel.print_for_con('Configuring security and authentication (note, that it is related only to web front-end):')
02690 
02691     # User CMD auth
02692     cm_kernel.print_for_con(line)
02693     cm_kernel.print_for_con('Allow access to cM front-end only to authenticated users:')
02694 
02695     if 'force_web_login' in d:
02696        cm_kernel.print_for_con('')
02697        cm_kernel.print_for_con('  Current setting is: '+d['force_web_login'])
02698 
02699     cm_kernel.print_for_con('')
02700     while True:
02701        var=raw_input('Would you like to force user authentication for web frontend (yes, no or press Enter to keep current setting): ')
02702        var=var.lower()
02703        if var=='' or var=='yes' or var=='no': break
02704 
02705     if var=='':
02706        cm_kernel.print_for_con('')
02707        cm_kernel.print_for_con('Keeping current setting ...')
02708     else:
02709        cm_kernel.print_for_con('')
02710        cm_kernel.print_for_con('Updating configuration file ...')
02711 
02712        d['force_web_login']=var
02713        if var=='yes': d['allow_web_user_auth']='yes'
02714 
02715        rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
02716        if rz['cm_return']>0: return rz
02717 
02718     if d.get('force_web_login','')!='yes':
02719 
02720        # Allow user authenticaton ****************
02721        cm_kernel.print_for_con(line)
02722        cm_kernel.print_for_con('Allow user authentication while using default user if not logged in :')
02723 
02724        if 'allow_web_user_auth' in d:
02725           cm_kernel.print_for_con('')
02726           cm_kernel.print_for_con('  Current setting is: '+d['allow_web_user_auth'])
02727 
02728        cm_kernel.print_for_con('')
02729        while True:
02730           var=raw_input('Would you like to allow user authentication (yes, no or press Enter to keep current setting): ')
02731           var=var.lower()
02732           if var=='' or var=='yes' or var=='no': break
02733 
02734        if var=='':
02735           cm_kernel.print_for_con('')
02736           cm_kernel.print_for_con('Keeping current setting ...')
02737        else:
02738           cm_kernel.print_for_con('')
02739           cm_kernel.print_for_con('Updating configuration file ...')
02740 
02741           d['allow_web_user_auth']=var
02742 
02743           rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
02744           if rz['cm_return']>0: return rz
02745 
02746     # forbid destructive actions
02747     cm_kernel.print_for_con(line)
02748     cm_kernel.print_for_con('Forbidding writing (or other destructive actions)')
02749 
02750     if 'forbid_write' in d:
02751        cm_kernel.print_for_con('')
02752        cm_kernel.print_for_con('  Current setting is: '+d['forbid_write'])
02753 
02754     cm_kernel.print_for_con('')
02755     cm_kernel.print_for_con('  We suggest to set "yes" for demo configurations when using on-line live repositories')
02756     cm_kernel.print_for_con('  and "no" in all other scenarios (private usage)')
02757 
02758     cm_kernel.print_for_con('')
02759     while True:
02760        var=raw_input('Would you like to forbid writing (yes, no or press Enter to keep current setting): ')
02761        var=var.lower()
02762        if var=='' or var=='yes' or var=='no': break
02763 
02764     if var=='':
02765        cm_kernel.print_for_con('')
02766        cm_kernel.print_for_con('Keeping current setting ...')
02767     else:
02768        cm_kernel.print_for_con('')
02769        cm_kernel.print_for_con('Updating configuration file ...')
02770 
02771        d['forbid_write']=var
02772 
02773        rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
02774        if rz['cm_return']>0: return rz
02775 
02776     # Checking local web ...
02777     dweb=d.get('cm_default_web_uoa','')
02778     if dweb=='':
02779        cm_kernel.print_for_con(line)
02780        cm_kernel.print_for_con('Default cM web server configuration is not set in kernel.')
02781        cm_kernel.print_for_con('We suggest you to copy "default" web configuration to "local" one')
02782        cm_kernel.print_for_con('and set it in kernel BUT ONLY IF YOU PLAN TO CHANGE DEFAULT HTTP PREFIX,')
02783        cm_kernel.print_for_con('I.E. IF YOU PLAN TO USE YOUR OWN HOSTING OR CHANGE DEFAULT PORT (3333), ETC.')
02784        cm_kernel.print_for_con('')
02785 
02786        while True:
02787           var=raw_input('Would you like to perform this operation (yes or no/Enter): ')
02788           var=var.lower()
02789           if var=='' or var=='yes' or var=='no': break
02790 
02791        if var=='no' or var=='': 
02792           # Load default web configuration
02793           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
02794               'cm_data_uoa':cm_kernel.var_cm_cfg_default,
02795               'cm_action':'load'}
02796           rz=cm_kernel.access(ii)
02797           if rz['cm_return']>0: return rz
02798 
02799        elif var=='yes':
02800           # Load default web configuration
02801           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
02802               'cm_data_uoa':cm_kernel.var_cm_cfg_default,
02803               'cm_action':'load'}
02804           rz=cm_kernel.access(ii)
02805           if rz['cm_return']>0: return rz
02806 
02807           dx=rz['cm_data_obj']['cfg']
02808 
02809           cm_kernel.print_for_con('')
02810           cm_kernel.print_for_con('Adding "local" web entry ...')
02811 
02812           dtmp=cm_kernel.ini['dcfg'].get('forbid_write',''); dtmp=cm_kernel.ini['dcfg']['forbid_write']='no'
02813           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
02814               'cm_data_uoa':cm_kernel.var_cm_cfg_local,
02815               'cm_action':'add',
02816               'cm_array':dx}
02817           rz=cm_kernel.access(ii)
02818           if rz['cm_return']>0: return rz
02819           cm_kernel.ini['dcfg']['forbid_write']=dtmp
02820 
02821        d['cm_default_web_uoa']=rz['cm_uid']
02822        dweb=rz['cm_uid']
02823 
02824        rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
02825        if rz['cm_return']>0: return rz
02826 
02827     # Check web address
02828     if dweb!='':
02829        cm_kernel.print_for_con(line)
02830        cm_kernel.print_for_con('')
02831        cm_kernel.print_for_con('Configuring web server http prefix ...')
02832 
02833        # Load default web configuration
02834        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
02835            'cm_data_uoa':dweb,
02836            'cm_action':'load'}
02837        rz=cm_kernel.access(ii)
02838        if rz['cm_return']>0: return rz
02839 
02840        dx=rz['cm_data_obj']['cfg']
02841 
02842        dy=dx.get('http_prefix','')
02843 
02844        cm_kernel.print_for_con('')
02845        cm_kernel.print_for_con('Current web server http prefix: '+dy)
02846 
02847        cm_kernel.print_for_con('')
02848        cm_kernel.print_for_con('Enter new http prefix (or press Enter to keep current setting)')
02849        var=raw_input('Example (http://localhost:3333?) : ')
02850     
02851        if var=='':
02852           cm_kernel.print_for_con('')
02853           cm_kernel.print_for_con('Keeping current setting ...')
02854        else:
02855           cm_kernel.print_for_con('')
02856           cm_kernel.print_for_con('Updating configuration file ...')
02857 
02858           dx['http_prefix']=var
02859 
02860           dtmp=cm_kernel.ini['dcfg'].get('forbid_write',''); dtmp=cm_kernel.ini['dcfg']['forbid_write']='no'
02861           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
02862               'cm_action':'update',
02863               'cm_array':dx,
02864               'cm_data_uoa':dweb}
02865           r=cm_kernel.access(ii)
02866           if r['cm_return']>0: return r
02867           cm_kernel.ini['dcfg']['forbid_write']=dtmp
02868 
02869        # Adding port for server
02870        dz=dx.get('cm_web_port','')
02871 
02872        cm_kernel.print_for_con('')
02873        cm_kernel.print_for_con('Current web port: '+dz)
02874 
02875        cm_kernel.print_for_con('')
02876        cm_kernel.print_for_con('Enter new port (or press Enter to keep current setting)')
02877        var=raw_input('(Make sure that it is the same as in http prefix above) : ')
02878     
02879        if var=='':
02880           cm_kernel.print_for_con('')
02881           cm_kernel.print_for_con('Keeping current setting ...')
02882        else:
02883           cm_kernel.print_for_con('')
02884           cm_kernel.print_for_con('Updating configuration file ...')
02885 
02886           dx['cm_web_port']=var
02887 
02888           dtmp=cm_kernel.ini['dcfg'].get('forbid_write',''); dtmp=cm_kernel.ini['dcfg']['forbid_write']='no'
02889           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
02890               'cm_action':'update',
02891               'cm_array':dx,
02892               'cm_data_uoa':dweb}
02893           r=cm_kernel.access(ii)
02894           if r['cm_return']>0: return r
02895           cm_kernel.ini['dcfg']['forbid_write']=dtmp
02896 
02897     # Checking indexing (should be at the very end since it turns on indexing and use need to start server) **********
02898     cm_kernel.print_for_con(line)
02899 
02900     cm_kernel.print_for_con('')
02901     cm_kernel.print_for_con('Configuring external indexing through ElasticSearch ...')
02902 
02903     # Checking local index ...
02904     dweb=d.get('cm_default_index_uoa','')
02905     if dweb=='' or dweb==ini['cfg']['cm_default_index_uoa']:
02906        cm_kernel.print_for_con(line)
02907        cm_kernel.print_for_con('Default cM index server configuration is not set in kernel.')
02908        cm_kernel.print_for_con('We suggest you to copy "default" web configuration to "local" one')
02909        cm_kernel.print_for_con('and set it in kernel BUT ONLY IF YOU PLAN TO CHANGE DEFAULT HTTP PREFIX,')
02910        cm_kernel.print_for_con('I.E. IF YOU PLAN TO USE YOUR OWN HOSTING OR CHANGE DEFAULT PORT (3333), ETC.')
02911        cm_kernel.print_for_con('')
02912 
02913        while True:
02914           var=raw_input('Would you like to perform this operation (yes or no/Enter): ')
02915           var=var.lower()
02916           if var=='' or var=='yes' or var=='no': break
02917 
02918        # Load default index configuration
02919        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
02920            'cm_data_uoa':cm_kernel.var_cm_cfg_default,
02921            'cm_action':'load'}
02922        rz=cm_kernel.access(ii)
02923        if rz['cm_return']>0: return rz
02924 
02925        if var=='yes':
02926           dz=rz['cm_data_obj']['cfg']
02927 
02928           cm_kernel.print_for_con('')
02929           cm_kernel.print_for_con('Adding "local" index entry ...')
02930 
02931           dtmp=cm_kernel.ini['dcfg'].get('forbid_write',''); dtmp=cm_kernel.ini['dcfg']['forbid_write']='no'
02932           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
02933               'cm_data_uoa':cm_kernel.var_cm_cfg_local,
02934               'cm_action':'add',
02935               'cm_array':dz}
02936           rz=cm_kernel.access(ii)
02937           if rz['cm_return']>0: return rz
02938           cm_kernel.ini['dcfg']['forbid_write']=dtmp
02939 
02940        d['cm_default_index_uoa']=rz['cm_uid']
02941 
02942        rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
02943        if rz['cm_return']>0: return rz
02944 
02945     # Check if want to use indexing
02946     if 'use_indexing' in d and d['use_indexing']!='':
02947         cm_kernel.print_for_con(line)
02948         cm_kernel.print_for_con('Current setting to use indexing: '+d['use_indexing'])
02949 
02950     cm_kernel.print_for_con('')
02951     while True:
02952        var=raw_input('Would you like to use indexing (yes, no or press Enter to keep current setting): ')
02953        var=var.lower()
02954        if var=='' or var=='yes' or var=='no': break
02955 
02956     if var=='':
02957        cm_kernel.print_for_con('')
02958        cm_kernel.print_for_con('Keeping current setting ...')
02959     else:
02960        cm_kernel.print_for_con('')
02961        cm_kernel.print_for_con('Updating configuration file ...')
02962 
02963        d['use_indexing']=var
02964 
02965        rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
02966        if rz['cm_return']>0: return rz
02967 
02968     cm_kernel.print_for_con('')
02969     cm_kernel.print_for_con('Confirming use of CURL for indexing - make sure that it is installed on Linux...')
02970   
02971     if 'use_curl_for_indexing' in d and d['use_curl_for_indexing']!='':
02972         cm_kernel.print_for_con('')
02973         cm_kernel.print_for_con('Current setting to use CURL: '+d['use_curl_for_indexing'])
02974 
02975     cm_kernel.print_for_con('')
02976     while True:
02977        var=raw_input('Would you like to use CURL for indexing (yes, no or press Enter to keep current setting): ')
02978        var=var.lower()
02979        if var=='' or var=='yes' or var=='no': break
02980 
02981     if var=='':
02982        cm_kernel.print_for_con('')
02983        cm_kernel.print_for_con('Keeping current setting ...')
02984     else:
02985        cm_kernel.print_for_con('')
02986        cm_kernel.print_for_con('Updating configuration file ...')
02987 
02988        d['use_curl_for_indexing']=var
02989 
02990        rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
02991        if rz['cm_return']>0: return rz
02992 
02993     # If use indexing, index one entry (module/module) to avoid errors with initial indexing
02994     if var=='yes' or d['use_indexing']=='yes':
02995        cm_kernel.print_for_con('')
02996        cm_kernel.print_for_con('Indexing one entry (module:core) for a test ...')
02997 
02998        dtmp=cm_kernel.ini['dcfg'].get('forbid_write',''); dtmp=cm_kernel.ini['dcfg']['forbid_write']='no'
02999        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
03000            'cm_action':'index',
03001            'cm_module_uoa':ini['cfg']['cm_modules']['cm-module'],
03002            'cm_data_uoa':ini['cm_module_uid'],
03003            'mode': 'add'}
03004        rx=cm_kernel.access(ii)
03005        cm_kernel.ini['dcfg']['forbid_write']=dtmp
03006        # TBD: for now ignore output of indexing to avoid problems
03007 
03008     # Check if want to download shared benchmarks, datasets, tools, etc from c-mind.org ************************
03009     cm_kernel.print_for_con(line)
03010     while True:
03011        cm_kernel.print_for_con('')
03012        cm_kernel.print_for_con('Would you like to download shared data (knowledge) from c-mind.org?')
03013        var=raw_input('  Strongly recommended (yes (or Enter), no ): ')
03014        var=var.lower()
03015        if var=='' or var=='yes' or var=='no': break
03016 
03017     if var=='no':
03018        cm_kernel.print_for_con('')
03019        cm_kernel.print_for_con('Skipping downloading. You can do it manually using command "cmx repo download" ...')
03020     else:
03021        while True:
03022           cm_kernel.print_for_con('')
03023           var=raw_input('Download (a)ll entries (can be very long) or only a (m)inimal set (default) (A/M)?')
03024           var=var.lower()
03025           if var=='' or var=='a' or var=='m': break
03026 
03027        cm_kernel.print_for_con('')
03028        cm_kernel.print_for_con('Downloading shared repositories ...')
03029 
03030        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
03031            'cm_action':'download'}
03032        if cm_default_user_uoa!='': ii['cm_remote_user_uoa']=cm_default_user_uoa
03033        if var=='a': ii['download_all']='yes'
03034        rx=cm_kernel.access(ii)
03035        if rx['cm_return']>0: return rx
03036 
03037     # Done
03038     cm_kernel.print_for_con(line)
03039     cm_kernel.print_for_con('cM minimal configuration is now finished. You can use advanced configuration using cM web-fronted')
03040     cm_kernel.print_for_con('')
03041     cm_kernel.print_for_con('If you find some bugs or have comments, do not hesitate to contact us at:')
03042     cm_kernel.print_for_con('  http://groups.google.com/group/collective-mind')
03043     cm_kernel.print_for_con('')
03044     cm_kernel.print_for_con('Note that you should restart your web server!')
03045 
03046     return {'cm_return':0}
03047 
03048 # ============================================================================
03049 def web_configure(i):
03050 
03051     """
03052     Configure some modules and params through web
03053 
03054     Input:  {
03055             }
03056 
03057     Output: {
03058               cm_return       - return code >0 if not authentificated
03059             }
03060     """
03061 
03062     # Get web style
03063     if 'cfg' in cm_kernel.ini['web_style']: web=cm_kernel.ini['web_style']['cfg']
03064     else:
03065        return {'cm_return':1, 'cm_error':'web style is not defined'}
03066 
03067     submit=False
03068     if 'cm_subaction_update_submit' in i: submit=True
03069 
03070     # Detecting/restoring data from forms
03071     a1={}
03072     r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
03073                         'cm_action':'detect_form_params',
03074                         'cm_array':i, 
03075                         'cm_prefix':'#form1'})
03076     if r['cm_return']>0: return r
03077     cm_form_array1=r['cm_array']
03078     cm_form_commands1=r['cm_commands']
03079 
03080     a2={}
03081     r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
03082                         'cm_action':'detect_form_params',
03083                         'cm_array':i, 
03084                         'cm_prefix':'#form2'})
03085     if r['cm_return']>0: return r
03086     cm_form_array2=r['cm_array']
03087     cm_form_commands2=r['cm_commands']
03088 
03089     a3={}
03090     r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
03091                         'cm_action':'detect_form_params',
03092                         'cm_array':i, 
03093                         'cm_prefix':'#form3'})
03094     if r['cm_return']>0: return r
03095     cm_form_array3=r['cm_array']
03096     cm_form_commands3=r['cm_commands']
03097 
03098     # Get data description for this action for kernel
03099     r=cm_kernel.get_data_description({'cm_module_uoa':ini['cm_module_uoa'], 
03100                                       'cm_which_action':i['cm_action']})
03101     if r['cm_return']>0: return r
03102     cm_data_desc1=r['cm_data_desc']
03103     cm_params_default1=r['cm_params_default']
03104 
03105     # Get data description for this action for OS
03106     r=cm_kernel.get_data_description({'cm_module_uoa':ini['cm_module_uoa'], 
03107                                       'cm_which_action':i['cm_action'],
03108                                       'cm_key':'params_desc_os'})
03109     if r['cm_return']>0: return r
03110     cm_data_desc2=r['cm_data_desc']
03111     cm_params_default2=r['cm_params_default']
03112 
03113     # Get data description for this action for Web
03114     r=cm_kernel.get_data_description({'cm_module_uoa':ini['cm_module_uoa'], 
03115                                       'cm_which_action':i['cm_action'],
03116                                       'cm_key':'params_desc_web'})
03117     if r['cm_return']>0: return r
03118     cm_data_desc3=r['cm_data_desc']
03119     cm_params_default3=r['cm_params_default']
03120 
03121     # Check default
03122     if len(cm_form_array1)==0:
03123        # Pre-load various parameters from different modules
03124        if 'cm_default_os_uoa' in cm_kernel.ini['dcfg']:
03125           a1['cm_default_os_uoa']=cm_kernel.ini['dcfg']['cm_default_os_uoa']
03126        if 'force_web_login' in cm_kernel.ini['dcfg']:
03127           a1['force_web_login']=cm_kernel.ini['dcfg']['force_web_login']
03128        if 'allow_web_user_auth' in cm_kernel.ini['dcfg']:
03129           a1['allow_web_user_auth']=cm_kernel.ini['dcfg']['allow_web_user_auth']
03130        if 'forbid_write' in cm_kernel.ini['dcfg']:
03131           a1['forbid_write']=cm_kernel.ini['dcfg']['forbid_write']
03132        if 'cm_default_web_uoa' in cm_kernel.ini['dcfg']:
03133           a1['cm_default_web_uoa']=cm_kernel.ini['dcfg']['cm_default_web_uoa']
03134        if 'use_indexing' in cm_kernel.ini['dcfg']:
03135           a1['use_indexing']=cm_kernel.ini['dcfg']['use_indexing']
03136        if 'cm_default_user_uoa' in cm_kernel.ini['dcfg']:
03137           a1['cm_default_user_uoa']=cm_kernel.ini['dcfg']['cm_default_user_uoa']
03138        if 'forbid_detached_console' in cm_kernel.ini['dcfg']:
03139           a1['forbid_detached_console']=cm_kernel.ini['dcfg']['forbid_detached_console']
03140 
03141     else:
03142        r=cm_kernel.restore_flattened_array({'cm_array':cm_form_array1, 
03143                                             'cm_replace_in_keys':{'^35^':'#', '^64^':'@'}})
03144        if r['cm_return']>0: return r
03145        a1=r['cm_array']
03146 
03147        r=cm_kernel.restore_flattened_array({'cm_array':cm_form_array2, 
03148                                             'cm_replace_in_keys':{'^35^':'#', '^64^':'@'}})
03149        if r['cm_return']>0: return r
03150        a2=r['cm_array']
03151 
03152        r=cm_kernel.restore_flattened_array({'cm_array':cm_form_array3, 
03153                                             'cm_replace_in_keys':{'^35^':'#', '^64^':'@'}})
03154        if r['cm_return']>0: return r
03155        a3=r['cm_array']
03156 
03157     # If there is data in form, means that refresh
03158     if not submit:
03159        forms_exists='yes'
03160        if len(cm_form_array1)==0:forms_exists='no'
03161 
03162        cm_kernel.print_for_con('<span class="cm-title">Configure main cM parameters</span><br><br>')
03163 
03164        cm_kernel.print_for_web('<FORM ACTION="" name="add_edit" METHOD="POST" enctype="multipart/form-data" accept-charset="utf-8">' )
03165 
03166        # add previous state (for OS and Web)
03167        cm_kernel.print_for_con('   <input type="hidden" name="state_cm_default_os_uoa" value="'+a1.get('cm_default_os_uoa','')+'">')
03168        cm_kernel.print_for_con('   <input type="hidden" name="state_cm_default_web_uoa" value="'+a1.get('cm_default_web_uoa','')+'">')
03169 
03170        cm_kernel.print_for_con('<B><I>Kernel:</I></B>' )
03171        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
03172            'cm_action':'visualize_data',
03173            'cm_array':a1,
03174            'cm_data_desc':cm_data_desc1,
03175            'cm_form_commands':cm_form_commands1,
03176            'cm_separator':'#',
03177            'cm_separator_form':'#form1#',
03178            'cm_forms_exists':forms_exists,
03179            'cm_support_raw_edit':'no',
03180            'cm_mode':'add'}
03181        if 'cm_raw_edit' in i: ii['cm_raw_edit']=i['cm_raw_edit']
03182        if 'cm_back_json' in i: ii['cm_back_json']=i['cm_back_json']
03183        r=cm_kernel.access(ii)
03184        if r['cm_return']>0: return r
03185        cm_kernel.print_for_web(r['cm_string'])
03186 
03187     # Check if OS in a1 and load it
03188     os_uoa=a1.get('cm_default_os_uoa','')
03189     if os_uoa!='':
03190        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['os'],
03191            'cm_action':'load',
03192            'cm_data_uoa':os_uoa}
03193        ros=cm_kernel.access(ii)
03194        if ros['cm_return']==0:
03195           dos=ros['cm_data_obj']['cfg']
03196 
03197           if not submit:
03198              if os_uoa!=i.get('state_cm_default_os_uoa', ''):
03199                 a2['cmd_for_detached_console']=dos.get('cmd_for_detached_console','')
03200                 a2['html_for_detached_console']=dos.get('html_for_detached_console','')
03201 
03202              cm_kernel.print_for_con('<br><B><I>OS ('+ros['cm_display_html']+'):</I></B>' )
03203              ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
03204                  'cm_action':'visualize_data',
03205                  'cm_array':a2,
03206                  'cm_data_desc':cm_data_desc2,
03207                  'cm_form_commands':cm_form_commands2,
03208                  'cm_separator':'#',
03209                  'cm_separator_form':'#form2#',
03210                  'cm_forms_exists':forms_exists,
03211                  'cm_support_raw_edit':'no',
03212                  'cm_mode':'add'}
03213              if 'cm_raw_edit' in i: ii['cm_raw_edit']=i['cm_raw_edit']
03214              if 'cm_back_json' in i: ii['cm_back_json']=i['cm_back_json']
03215              r=cm_kernel.access(ii)
03216              if r['cm_return']>0: return r
03217              cm_kernel.print_for_web(r['cm_string'])
03218 
03219     # Check if Web in a1 and load it
03220     web_uoa=a1.get('cm_default_web_uoa','')
03221     if web_uoa!='':
03222        ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
03223            'cm_action':'load',
03224            'cm_data_uoa':web_uoa}
03225        rweb=cm_kernel.access(ii)
03226        if rweb['cm_return']==0:
03227           dweb=rweb['cm_data_obj']['cfg']
03228 
03229           if not submit:
03230              if web_uoa!=i.get('state_cm_default_web_uoa', ''):
03231                 a3['http_prefix']=dweb.get('http_prefix','')
03232                 a3['cm_menu_default']=dweb.get('cm_menu_default','')
03233                 a3['customized_module_welcome']=dweb.get('customized_module_welcome','')
03234                 a3['customized_module_scenarios']=dweb.get('customized_module_scenarios','')
03235 
03236              cm_kernel.print_for_con('<br><B><I>Web ('+rweb['cm_display_html']+'):</I></B>' )
03237              ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
03238                  'cm_action':'visualize_data',
03239                  'cm_array':a3,
03240                  'cm_data_desc':cm_data_desc3,
03241                  'cm_form_commands':cm_form_commands3,
03242                  'cm_separator':'#',
03243                  'cm_separator_form':'#form3#',
03244                  'cm_forms_exists':forms_exists,
03245                  'cm_support_raw_edit':'no',
03246                  'cm_mode':'add'}
03247              if 'cm_raw_edit' in i: ii['cm_raw_edit']=i['cm_raw_edit']
03248              if 'cm_back_json' in i: ii['cm_back_json']=i['cm_back_json']
03249              r=cm_kernel.access(ii)
03250              if r['cm_return']>0: return r
03251              cm_kernel.print_for_web(r['cm_string'])
03252 
03253     if not submit:
03254        x='<br><input type="submit" class="cm-button" value="Refresh">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
03255        x+='<input type="submit" class="cm-button" name="cm_subaction_update_submit" value="Update"><br><br>'
03256        cm_kernel.print_for_con(x)
03257        cm_kernel.print_for_con('</FORM>')
03258     else:
03259        # Update kernel
03260        pcfg=cm_kernel.ini['pcfg']
03261        if pcfg=='':
03262           return {'cm_return':1, 'cm_error':'default kernel path is not found'}
03263 
03264        pcfg=cm_kernel.ini['pcfg']
03265 
03266        ra=cm_kernel.load_json_file({'cm_filename':pcfg})
03267        if ra['cm_return']>0: return ra
03268        d=ra['cm_array']
03269 
03270        # Since it's a direct rewrite, check if writing is forbidden explicitly!
03271        r=cm_kernel.check_global_writing({})
03272        if r['cm_return']>0: return r
03273    
03274        d.update(a1)
03275 
03276        rz=cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
03277        if rz['cm_return']>0: return rz
03278 
03279        # Update OS
03280        if os_uoa!='' and (dos['cmd_for_detached_console']!=a2['cmd_for_detached_console'] or \
03281                           dos['html_for_detached_console']!=a2['html_for_detached_console']):
03282           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['os'],
03283               'cm_action':'update',
03284               'cm_array':a2,
03285               'cm_data_uoa':os_uoa}
03286           r=cm_kernel.access(ii)
03287           if r['cm_return']>0: return r
03288 
03289        # Update Web
03290        if web_uoa!='' and (dweb['http_prefix']!=a3['http_prefix'] or \
03291                            dweb['cm_menu_default']!=a3['cm_menu_default'] or \
03292                            dweb.get('customized_module_welcome','')!=a3['customized_module_welcome'] or \
03293                            dweb.get('customized_module_scenarios','')!=a3['customized_module_scenarios']):
03294           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-web'],
03295               'cm_action':'update',
03296               'cm_array':a3,
03297               'cm_data_uoa':web_uoa}
03298           r=cm_kernel.access(ii)
03299           if r['cm_return']>0: return r
03300 
03301        # If use indexing, index one entry (module/module) to avoid errors with initial indexing
03302        if a1.get('use_indexing','')=='yes':
03303           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
03304               'cm_action':'index',
03305               'cm_module_uoa':ini['cfg']['cm_modules']['cm-module'],
03306               'cm_data_uoa':ini['cm_module_uid'],
03307               'mode': 'add',
03308               'cm_console':''}
03309           rx=cm_kernel.access(ii)
03310           # TBD: for now ignore output of indexing to avoid problems
03311 
03312        # Finish
03313        cm_kernel.print_for_con('<br>Kernel, OS and Web were updated successfully!<br><br>')
03314        cm_kernel.print_for_con('<b><i>Note that you should restart your web server!<i></b><br><br>')
03315 
03316     return {'cm_return':0}
03317 
03318 # ============================================================================
03319 def temporaly_allow_writing_in_kernel(i):
03320 
03321     """
03322     Temporally allow writing in kernel
03323 
03324     Input:  {
03325               cm_filename - filename with full path to the current kernel configuration
03326               cm_array    - current configuration array
03327             }
03328 
03329     Output: {
03330               cm_return  - return code >0 if error
03331             }
03332     """
03333 
03334     dtmp=i['cm_array'].get('forbid_write','')
03335     i['cm_array']['forbid_write']='no'
03336 
03337     rz=cm_kernel.save_array_to_file_as_json(i)
03338 
03339     i['cm_array']['forbid_write']=dtmp
03340 
03341     return rz
03342 
03343 # ============================================================================
03344 def restore_writing_in_kernel(i):
03345 
03346     """
03347     Restore writing in kernel
03348 
03349     Input:  {
03350               cm_filename - filename with full path to the current kernel configuration
03351               cm_array    - current configuration array
03352             }
03353 
03354     Output: {
03355               cm_return  - return code >0 if error
03356             }
03357     """
03358 
03359     return cm_kernel.save_array_to_file_as_json(i)
03360 
03361 # ============================================================================
03362 def gen_cm_tmp_file(i):
03363 
03364     """
03365     Generate tmp file name
03366 
03367     Input:  {}
03368 
03369     Output: {
03370               cm_return  - return code >0 if error
03371               cm_path    - path to file
03372               cm_uid     - generated uid
03373             }
03374     """
03375 
03376     r=cm_kernel.gen_cm_tmp_file(i)
03377     if r['cm_return']>0: return r
03378 
03379     if i.get('cm_console')=='txt':
03380        cm_kernel.print_for_con('Path: '+r['cm_path'])
03381        cm_kernel.print_for_con('UID:  '+r['cm_uid'])
03382 
03383     return r
03384 
03385 # ============================================================================
03386 def get_info_about_current_path(i):
03387 
03388     """
03389     Get info about current path
03390 
03391     Input:  {}
03392 
03393     Output: {
03394               cm_return       - return code >0 if error
03395                                             -1 if doesn't exist
03396               cm_path         - path to the local repository
03397               (cm_module_uoa) - module UOA of the current path
03398               (cm_data_uoa)   - data UOA of the current path
03399               (cm_repo_uoa)   - repo UOA
03400               (cm_repo_uid)   - repo UID
03401             }
03402     """
03403 
03404     # Get paths of all repos for UOA/UID
03405     r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
03406                         'cm_action':'get_all_repo_paths'})
03407     if r['cm_return']>0: return r
03408 
03409     repos=r['cm_array']
03410 
03411     # Get current path
03412     r=cm_kernel.find_path_to_current_repository(i)
03413     if r['cm_return']!=0: return r
03414 
03415     for x in repos:
03416         if r['cm_path']==x['cm_path']:
03417            r['cm_repo_uoa']=x['cm_uoa']
03418            r['cm_repo_uid']=x['cm_uid']
03419            break
03420 
03421     return r
03422 
03423 # ============================================================================
03424 def get_info_about_full_hosts(i):
03425 
03426     """
03427     Get info about current full web and index hosts
03428 
03429     Input:  {}
03430 
03431     Output: {
03432               cm_return       - return code >0 if error
03433               cm_web_host     - full web host 
03434               cm_index_host   - full indexing host
03435             }
03436     """
03437 
03438     rr={'cm_return':0}
03439 
03440     # Get web style
03441     if 'cfg' in cm_kernel.ini['web_style']: web=cm_kernel.ini['web_style']['cfg']
03442     else:
03443        return {'cm_return':1, 'cm_error':'web style is not defined'}
03444 
03445     rr['cm_web_host']=web['http_prefix']
03446 
03447     # Check (default) index configuration
03448     index_uoa='default'
03449     if 'cm_index_uoa' in i and i['cm_index_uoa']!='': index_uoa=i['cm_index_uoa']
03450     elif 'cm_default_index_uoa' in cm_kernel.ini['dcfg'] and cm_kernel.ini['dcfg']['cm_default_index_uoa']!='':
03451        index_uoa=cm_kernel.ini['dcfg']['cm_default_index_uoa']
03452 
03453     if index_uoa=='':
03454        return {'cm_return':1, 'cm_error':'"cm_index_uoa" is not defined'}
03455 
03456     # Load index
03457     r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-index'],
03458                         'cm_action':'load',
03459                         'cm_data_uoa':index_uoa})
03460     if r['cm_return']>0: return r
03461     index_cfg=r['cm_data_obj']['cfg']
03462 
03463     port=index_cfg.get('port','9200')
03464     support_port=index_cfg.get('support_port','9300')
03465     index_host=index_cfg['host']+':'+port
03466 
03467     rr['cm_index_host']=index_host
03468 
03469     if i.get('cm_console','')=='txt':
03470        cm_kernel.print_for_con(rr['cm_web_host'])
03471        cm_kernel.print_for_con(rr['cm_index_host'])
03472 
03473     return rr
03474 
03475 # ============================================================================
03476 def load_default_kernel_data(i):
03477 
03478     """
03479     Load default kernel data
03480 
03481     Input:  {
03482             }                                   
03483     Output: {
03484               cm_return            - return code = 0, if successful
03485                                                  < 0, if error
03486                                                       32 - lock acquired by someone else
03487                                                            
03488               (cm_error)           - error text if return code > 0
03489               cm_data_obj          - cM data object
03490             }
03491     """
03492 
03493     # Get path to current kernel data
03494     pcfg=cm_kernel.ini['pcfg']
03495 
03496     # Load clean kernel data
03497     ra=cm_kernel.load_json_file({'cm_filename':pcfg})
03498     if ra['cm_return']>0: return ra
03499     d=ra['cm_array']
03500 
03501     return {'cm_return':0, 'cm_data_obj':{'cfg':d}}
03502 
03503 # ============================================================================
03504 def update_default_kernel_data(i):
03505 
03506     """
03507     Update default kernel data
03508 
03509     Input:  {
03510               cm_array             - data to update
03511             }                                   
03512     Output: {
03513               cm_return            - return code = 0, if successful
03514                                                  < 0, if error
03515                                                       32 - lock acquired by someone else
03516                                                            
03517               (cm_error)           - error text if return code > 0
03518             }
03519     """
03520 
03521     # Get path to current kernel data
03522     pcfg=cm_kernel.ini['pcfg']
03523 
03524     # Load clean kernel data
03525     ra=cm_kernel.load_json_file({'cm_filename':pcfg})
03526     if ra['cm_return']>0: return ra
03527     d=ra['cm_array']
03528 
03529     a=i.get('cm_array',{})
03530 
03531     # Merge arrays
03532     r=cm_kernel.merge_arrays({'cm_array':d, 'cm_array1':a})
03533     if r['cm_return']>0: return r
03534 
03535     # Save kernel data
03536     return cm_kernel.save_array_to_file_as_json({'cm_filename':pcfg, 'cm_array':d})
03537 
03538 # ============================================================================
03539 def get_list_of_all_files(i):
03540     """
03541     Get a list of all files in a given directory recursively
03542 
03543     Input:  {
03544               cm_module_uoa - module UOA
03545               cm_data_uoa   - data UOA
03546               (cm_repo_uoa) - repo UOA
03547               cm_path_ext  - path extension
03548               limit        - limit number of files (if huge directories)
03549               number       - cur. number of files
03550               cm_all_files - if 'yes' do not ignore special files (like .cm)
03551             }
03552 
03553     Output: {
03554               cm_return - return code = 0 if successful
03555               cm_array  - list of files
03556             }
03557     """
03558 
03559     # Load data
03560     jj={}
03561     if i.get('cm_repo_uoa','')!='': jj['cm_repo_uoa']=i['cm_repo_uoa']
03562     if i.get('cm_module_uoa','')!='': jj['cm_module_uoa']=i['cm_module_uoa']
03563     if i.get('cm_data_uoa','')!='': jj['cm_data_uoa']=i['cm_data_uoa']
03564     r=load_data(jj)
03565     if r['cm_return']>0: return r
03566 
03567     path=r['cm_path']
03568 
03569     if i.get('cm_module_uoa','')!='': del(i['cm_module_uoa'])
03570     if i.get('cm_data_uoa','')!='': del(i['cm_data_uoa'])
03571     if i.get('cm_repo_uoa','')!='': del(i['cm_repo_uoa'])
03572 
03573     i['cm_path']=path
03574 
03575     return cm_kernel.get_list_of_all_files(i)
03576 
03577 # ============================================================================
03578 def convert_file_to_upload_string(i):
03579     """
03580     Convert file to upload string
03581 
03582     Input:  {
03583               cm_full_filename - file name to convert
03584             }
03585 
03586     Output: {
03587               cm_return            - return code =0 if successful
03588                                                  >0 if error
03589               cm_file_upload_base64 - string that can be used to upload file
03590             }
03591     """
03592 
03593     r=cm_kernel.convert_file_to_upload_string(i)
03594     if r['cm_return']>0: return r
03595 
03596     if i.get('cm_console','')=='txt':
03597        cm_kernel.print_for_con(r['cm_file_upload_base64'])
03598 
03599     return r

Generated on Wed May 28 02:49:01 2014 for Collective Mind Framework by DoxyGen 1.6.1
Concept, design and coordination: Grigori Fursin (C) 1993-2013