1 """turn a pyro source into a datafeed source |
|
2 |
|
3 Once this script is run, execute c-c db-check to cleanup relation tables. |
|
4 """ |
|
5 from __future__ import print_function |
|
6 |
|
7 import sys |
|
8 |
|
9 try: |
|
10 source_name, = __args__ |
|
11 source = repo.sources_by_uri[source_name] |
|
12 except ValueError: |
|
13 print('you should specify the source name as script argument (i.e. after --' |
|
14 ' on the command line)') |
|
15 sys.exit(1) |
|
16 except KeyError: |
|
17 print('%s is not an active source' % source_name) |
|
18 sys.exit(1) |
|
19 |
|
20 # check source is reachable before doing anything |
|
21 try: |
|
22 source.get_connection()._repo |
|
23 except AttributeError: |
|
24 print('%s is not reachable. Fix this before running this script' % source_name) |
|
25 sys.exit(1) |
|
26 |
|
27 raw_input('Ensure you have shutdown all instances of this application before continuing.' |
|
28 ' Type enter when ready.') |
|
29 |
|
30 system_source = repo.system_source |
|
31 |
|
32 from base64 import b64encode |
|
33 from cubicweb.server.edition import EditedEntity |
|
34 |
|
35 DONT_GET_BACK_ETYPES = set(( # XXX edit as desired |
|
36 'State', |
|
37 'RecipeStep', 'RecipeStepInput', 'RecipeStepOutput', |
|
38 'RecipeTransition', 'RecipeTransitionCondition', |
|
39 'NarvalConditionExpression', 'Recipe', |
|
40 # XXX TestConfig |
|
41 )) |
|
42 |
|
43 |
|
44 print('******************** backport entity content ***************************') |
|
45 |
|
46 from cubicweb.server import debugged |
|
47 todelete = {} |
|
48 host = source.config['base-url'].split('://')[1] |
|
49 for entity in rql('Any X WHERE X cw_source S, S eid %(s)s', {'s': source.eid}).entities(): |
|
50 etype = entity.cw_etype |
|
51 if not source.support_entity(etype): |
|
52 print("source doesn't support %s, delete %s" % (etype, entity.eid)) |
|
53 elif etype in DONT_GET_BACK_ETYPES: |
|
54 print('ignore %s, delete %s' % (etype, entity.eid)) |
|
55 else: |
|
56 try: |
|
57 entity.complete() |
|
58 if not host in entity.cwuri: |
|
59 print('SKIP foreign entity', entity.cwuri, source.config['base-url']) |
|
60 continue |
|
61 except Exception: |
|
62 print('%s %s much probably deleted, delete it (extid %s)' % ( |
|
63 etype, entity.eid, entity.cw_metainformation()['extid'])) |
|
64 else: |
|
65 print('get back', etype, entity.eid) |
|
66 entity.cw_edited = EditedEntity(entity, **entity.cw_attr_cache) |
|
67 system_source.add_entity(session, entity) |
|
68 sql("UPDATE entities SET asource=%(asource)s, source='system', extid=%(extid)s " |
|
69 "WHERE eid=%(eid)s", {'asource': source_name, |
|
70 'extid': b64encode(entity.cwuri), |
|
71 'eid': entity.eid}) |
|
72 continue |
|
73 todelete.setdefault(etype, []).append(entity) |
|
74 |
|
75 # only cleanup entities table, remaining stuff should be cleaned by a c-c |
|
76 # db-check to be run after this script |
|
77 for entities in todelete.values(): |
|
78 system_source.delete_info_multi(session, entities, source_name) |
|
79 |
|
80 |
|
81 print('******************** backport mapping **********************************') |
|
82 session.disable_hook_categories('cw.sources') |
|
83 mapping = [] |
|
84 for mappart in rql('Any X,SCH WHERE X cw_schema SCH, X cw_for_source S, S eid %(s)s', |
|
85 {'s': source.eid}).entities(): |
|
86 schemaent = mappart.cw_schema[0] |
|
87 if schemaent.cw_etype != 'CWEType': |
|
88 assert schemaent.cw_etype == 'CWRType' |
|
89 sch = schema._eid_index[schemaent.eid] |
|
90 for rdef in sch.rdefs.values(): |
|
91 if not source.support_entity(rdef.subject) \ |
|
92 or not source.support_entity(rdef.object): |
|
93 continue |
|
94 if rdef.subject in DONT_GET_BACK_ETYPES \ |
|
95 and rdef.object in DONT_GET_BACK_ETYPES: |
|
96 print('dont map', rdef) |
|
97 continue |
|
98 if rdef.subject in DONT_GET_BACK_ETYPES: |
|
99 options = u'action=link\nlinkattr=name' |
|
100 roles = 'object', |
|
101 elif rdef.object in DONT_GET_BACK_ETYPES: |
|
102 options = u'action=link\nlinkattr=name' |
|
103 roles = 'subject', |
|
104 else: |
|
105 options = u'action=copy' |
|
106 if rdef.rtype in ('use_environment',): |
|
107 roles = 'object', |
|
108 else: |
|
109 roles = 'subject', |
|
110 print('map', rdef, options, roles) |
|
111 for role in roles: |
|
112 mapping.append( ( |
|
113 (str(rdef.subject), str(rdef.rtype), str(rdef.object)), |
|
114 options + '\nrole=%s' % role) ) |
|
115 mappart.cw_delete() |
|
116 |
|
117 source_ent = rql('CWSource S WHERE S eid %(s)s', {'s': source.eid}).get_entity(0, 0) |
|
118 source_ent.init_mapping(mapping) |
|
119 |
|
120 # change source properties |
|
121 config = u'''synchronize=yes |
|
122 synchronization-interval=10min |
|
123 delete-entities=no |
|
124 ''' |
|
125 rql('SET X type "datafeed", X parser "cw.entityxml", X url %(url)s, X config %(config)s ' |
|
126 'WHERE X eid %(x)s', |
|
127 {'x': source.eid, 'config': config, |
|
128 'url': source.config['base-url']+'/project'}) |
|
129 |
|
130 |
|
131 commit() |
|
132 |
|
133 from cubes.apycot import recipes |
|
134 recipes.create_quick_recipe(session) |
|