[server] Port BFSS to py3k
The BFSS API changes in python 3:
* 'defaultdir' MUST be a unicode object
* 'fsencoding' MUST NOT be set
In python 2, fsencoding handles both the encoding of file paths on the
file system (utf-8 by default, but the system may actually be using
something else) and the encoding of file paths that will be stored in
the database.
So in python 3, we wipe the slate clean:
* rely on sys.getfilesystemencoding() to convert unicode objects to
bytes
* always encode paths to utf-8 for storage in the database
Caveat emptor / here be dragons:
* sys.getfilesystemencoding() depends on the current locale, which
therefore MUST be set properly
* when migrating an existing instance from py2 to py3, one MAY need
to reencode file paths stored in the database
"""turn a pyro source into a datafeed sourceOnce this script is run, execute c-c db-check to cleanup relation tables."""from__future__importprint_functionimportsystry:source_name,=__args__source=repo.sources_by_uri[source_name]exceptValueError:print('you should specify the source name as script argument (i.e. after --'' on the command line)')sys.exit(1)exceptKeyError:print('%s is not an active source'%source_name)sys.exit(1)# check source is reachable before doing anythingtry:source.get_connection()._repoexceptAttributeError:print('%s is not reachable. Fix this before running this script'%source_name)sys.exit(1)raw_input('Ensure you have shutdown all instances of this application before continuing.'' Type enter when ready.')system_source=repo.system_sourcefrombase64importb64encodefromcubicweb.server.editionimportEditedEntityDONT_GET_BACK_ETYPES=set((# XXX edit as desired'State','RecipeStep','RecipeStepInput','RecipeStepOutput','RecipeTransition','RecipeTransitionCondition','NarvalConditionExpression','Recipe',# XXX TestConfig))print('******************** backport entity content ***************************')fromcubicweb.serverimportdebuggedtodelete={}host=source.config['base-url'].split('://')[1]forentityinrql('Any X WHERE X cw_source S, S eid %(s)s',{'s':source.eid}).entities():etype=entity.cw_etypeifnotsource.support_entity(etype):print("source doesn't support %s, delete %s"%(etype,entity.eid))elifetypeinDONT_GET_BACK_ETYPES:print('ignore %s, delete %s'%(etype,entity.eid))else:try:entity.complete()ifnothostinentity.cwuri:print('SKIP foreign entity',entity.cwuri,source.config['base-url'])continueexceptException:print('%s%s much probably deleted, delete it (extid %s)'%(etype,entity.eid,entity.cw_metainformation()['extid']))else:print('get back',etype,entity.eid)entity.cw_edited=EditedEntity(entity,**entity.cw_attr_cache)system_source.add_entity(session,entity)sql("UPDATE entities SET asource=%(asource)s, source='system', extid=%(extid)s ""WHERE eid=%(eid)s",{'asource':source_name,'extid':b64encode(entity.cwuri),'eid':entity.eid})continuetodelete.setdefault(etype,[]).append(entity)# only cleanup entities table, remaining stuff should be cleaned by a c-c# db-check to be run after this scriptforentitiesintodelete.values():system_source.delete_info_multi(session,entities,source_name)print('******************** backport mapping **********************************')session.disable_hook_categories('cw.sources')mapping=[]formappartinrql('Any X,SCH WHERE X cw_schema SCH, X cw_for_source S, S eid %(s)s',{'s':source.eid}).entities():schemaent=mappart.cw_schema[0]ifschemaent.cw_etype!='CWEType':assertschemaent.cw_etype=='CWRType'sch=schema._eid_index[schemaent.eid]forrdefinsch.rdefs.values():ifnotsource.support_entity(rdef.subject) \ornotsource.support_entity(rdef.object):continueifrdef.subjectinDONT_GET_BACK_ETYPES \andrdef.objectinDONT_GET_BACK_ETYPES:print('dont map',rdef)continueifrdef.subjectinDONT_GET_BACK_ETYPES:options=u'action=link\nlinkattr=name'roles='object',elifrdef.objectinDONT_GET_BACK_ETYPES:options=u'action=link\nlinkattr=name'roles='subject',else:options=u'action=copy'ifrdef.rtypein('use_environment',):roles='object',else:roles='subject',print('map',rdef,options,roles)forroleinroles:mapping.append(((str(rdef.subject),str(rdef.rtype),str(rdef.object)),options+'\nrole=%s'%role))mappart.cw_delete()source_ent=rql('CWSource S WHERE S eid %(s)s',{'s':source.eid}).get_entity(0,0)source_ent.init_mapping(mapping)# change source propertiesconfig=u'''synchronize=yessynchronization-interval=10mindelete-entities=no'''rql('SET X type "datafeed", X parser "cw.entityxml", X url %(url)s, X config %(config)s ''WHERE X eid %(x)s',{'x':source.eid,'config':config,'url':source.config['base-url']+'/project'})commit()fromcubes.apycotimportrecipesrecipes.create_quick_recipe(session)