[sources] Drop source support_entity / support_relation source API
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 28 Sep 2016 22:17:36 +0200
changeset 11750 18e7b9829471
parent 11749 ae9789d77ea0
child 11751 b57b76091481
[sources] Drop source support_entity / support_relation source API this was used in the pre-datafeed area, it's not worth it anymore. Its only valid usage was in authentication to detect if the source was supporting CWUser, hence we now call it systematically and catch NotImplementedError.
cubicweb/misc/scripts/ldapuser2ldapfeed.py
cubicweb/misc/scripts/pyroforge2datafeed.py
cubicweb/server/repository.py
cubicweb/server/sources/__init__.py
cubicweb/server/sources/native.py
--- a/cubicweb/misc/scripts/ldapuser2ldapfeed.py	Fri Sep 30 18:24:17 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-"""turn a pyro source into a datafeed source
-
-Once this script is run, execute c-c db-check to cleanup relation tables.
-"""
-from __future__ import print_function
-
-import sys
-from collections import defaultdict
-from logilab.common.shellutils import generate_password
-
-try:
-    source_name, = __args__
-    source = repo.sources_by_uri[source_name]
-except ValueError:
-    print('you should specify the source name as script argument (i.e. after --'
-          ' on the command line)')
-    sys.exit(1)
-except KeyError:
-    print('%s is not an active source' % source_name)
-    sys.exit(1)
-
-# check source is reachable before doing anything
-if not source.get_connection().cnx:
-    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_source
-
-from datetime import datetime
-from cubicweb.server.edition import EditedEntity
-
-
-print('******************** backport entity content ***************************')
-
-todelete = defaultdict(list)
-extids = set()
-duplicates = []
-for entity in rql('Any X WHERE X cw_source S, S eid %(s)s', {'s': source.eid}).entities():
-    etype = entity.cw_etype
-    if not source.support_entity(etype):
-        print("source doesn't support %s, delete %s" % (etype, entity.eid))
-        todelete[etype].append(entity)
-        continue
-    try:
-        entity.complete()
-    except Exception:
-        print('%s %s much probably deleted, delete it (extid %s)' % (
-            etype, entity.eid, entity.cw_metainformation()['extid']))
-        todelete[etype].append(entity)
-        continue
-    print('get back', etype, entity.eid)
-    entity.cw_edited = EditedEntity(entity, **entity.cw_attr_cache)
-    if not entity.creation_date:
-        entity.cw_edited['creation_date'] = datetime.utcnow()
-    if not entity.modification_date:
-        entity.cw_edited['modification_date'] = datetime.utcnow()
-    if not entity.upassword:
-        entity.cw_edited['upassword'] = generate_password()
-    extid = entity.cw_metainformation()['extid']
-    if not entity.cwuri:
-        entity.cw_edited['cwuri'] = '%s/?dn=%s' % (
-            source.urls[0], extid.decode('utf-8', 'ignore'))
-    print(entity.cw_edited)
-    if extid in extids:
-        duplicates.append(extid)
-        continue
-    extids.add(extid)
-    system_source.add_entity(session, entity)
-    sql("UPDATE entities SET source='system' "
-        "WHERE eid=%(eid)s", {'eid': entity.eid})
-
-# only cleanup entities table, remaining stuff should be cleaned by a c-c
-# db-check to be run after this script
-if duplicates:
-    print('found %s duplicate entries' % len(duplicates))
-    from pprint import pprint
-    pprint(duplicates)
-
-print(len(todelete), 'entities will be deleted')
-for etype, entities in todelete.items():
-    print('deleting', etype, [e.login for e in entities])
-    system_source.delete_info_multi(session, entities, source_name)
-
-
-
-source_ent = rql('CWSource S WHERE S eid %(s)s', {'s': source.eid}).get_entity(0, 0)
-source_ent.cw_set(type=u"ldapfeed", parser=u"ldapfeed")
-
-
-if raw_input('Commit?') in 'yY':
-    print('committing')
-    commit()
-else:
-    rollback()
-    print('rolled back')
--- a/cubicweb/misc/scripts/pyroforge2datafeed.py	Fri Sep 30 18:24:17 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-"""turn a pyro source into a datafeed source
-
-Once this script is run, execute c-c db-check to cleanup relation tables.
-"""
-from __future__ import print_function
-
-import sys
-
-try:
-    source_name, = __args__
-    source = repo.sources_by_uri[source_name]
-except ValueError:
-    print('you should specify the source name as script argument (i.e. after --'
-          ' on the command line)')
-    sys.exit(1)
-except KeyError:
-    print('%s is not an active source' % source_name)
-    sys.exit(1)
-
-# check source is reachable before doing anything
-try:
-    source.get_connection()._repo
-except AttributeError:
-    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_source
-
-from base64 import b64encode
-from cubicweb.server.edition import EditedEntity
-
-DONT_GET_BACK_ETYPES = set(( # XXX edit as desired
-        'State',
-        'RecipeStep', 'RecipeStepInput', 'RecipeStepOutput',
-        'RecipeTransition', 'RecipeTransitionCondition',
-        'NarvalConditionExpression', 'Recipe',
-        # XXX TestConfig
-        ))
-
-
-print('******************** backport entity content ***************************')
-
-from cubicweb.server import debugged
-todelete = {}
-host = source.config['base-url'].split('://')[1]
-for entity in rql('Any X WHERE X cw_source S, S eid %(s)s', {'s': source.eid}).entities():
-        etype = entity.cw_etype
-        if not source.support_entity(etype):
-            print("source doesn't support %s, delete %s" % (etype, entity.eid))
-        elif etype in DONT_GET_BACK_ETYPES:
-            print('ignore %s, delete %s' % (etype, entity.eid))
-        else:
-            try:
-                entity.complete()
-                if not host in entity.cwuri:
-                    print('SKIP foreign entity', entity.cwuri, source.config['base-url'])
-                    continue
-            except Exception:
-                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})
-                continue
-        todelete.setdefault(etype, []).append(entity)
-
-# only cleanup entities table, remaining stuff should be cleaned by a c-c
-# db-check to be run after this script
-for entities in todelete.values():
-    system_source.delete_info_multi(session, entities, source_name)
-
-
-print('******************** backport mapping **********************************')
-session.disable_hook_categories('cw.sources')
-mapping = []
-for mappart in rql('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]
-    if schemaent.cw_etype != 'CWEType':
-        assert schemaent.cw_etype == 'CWRType'
-        sch = schema._eid_index[schemaent.eid]
-        for rdef in sch.rdefs.values():
-            if not source.support_entity(rdef.subject) \
-                    or not source.support_entity(rdef.object):
-                continue
-            if rdef.subject in DONT_GET_BACK_ETYPES \
-                    and rdef.object in DONT_GET_BACK_ETYPES:
-                print('dont map', rdef)
-                continue
-            if rdef.subject in DONT_GET_BACK_ETYPES:
-                options = u'action=link\nlinkattr=name'
-                roles = 'object',
-            elif rdef.object in DONT_GET_BACK_ETYPES:
-                options = u'action=link\nlinkattr=name'
-                roles = 'subject',
-            else:
-                options = u'action=copy'
-                if rdef.rtype in ('use_environment',):
-                    roles = 'object',
-                else:
-                    roles = 'subject',
-            print('map', rdef, options, roles)
-            for role in roles:
-                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 properties
-config = u'''synchronize=yes
-synchronization-interval=10min
-delete-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()
-
-from cubes.apycot import recipes
-recipes.create_quick_recipe(session)
--- a/cubicweb/server/repository.py	Fri Sep 30 18:24:17 2016 +0200
+++ b/cubicweb/server/repository.py	Wed Sep 28 22:17:36 2016 +0200
@@ -454,10 +454,10 @@
         # iter on sources_by_uri then check enabled source since sources doesn't
         # contain copy based sources
         for source in self.sources_by_uri.values():
-            if self.config.source_enabled(source) and source.support_entity('CWUser'):
+            if self.config.source_enabled(source):
                 try:
                     return source.authenticate(cnx, login, **authinfo)
-                except AuthenticationError:
+                except (NotImplementedError, AuthenticationError):
                     continue
         else:
             raise AuthenticationError('authentication failed with all sources')
--- a/cubicweb/server/sources/__init__.py	Fri Sep 30 18:24:17 2016 +0200
+++ b/cubicweb/server/sources/__init__.py	Wed Sep 28 22:17:36 2016 +0200
@@ -71,11 +71,6 @@
     # migration
     connect_for_migration = True
 
-    # mappings telling which entities and relations are available in the source
-    # keys are supported entity/relation types and values are boolean indicating
-    # wether the support is read-only (False) or read-write (True)
-    support_entities = {}
-    support_relations = {}
     # a global identifier for this source, which has to be set by the source
     # instance
     uri = None
@@ -101,7 +96,6 @@
     def __init__(self, repo, source_config, eid=None):
         self.repo = repo
         self.set_schema(repo.schema)
-        self.support_relations['identity'] = False
         self.eid = eid
         self.public_config = source_config.copy()
         self.public_config['use-cwuri-as-url'] = self.use_cwuri_as_url
@@ -264,44 +258,6 @@
 
     # external source api ######################################################
 
-    def support_entity(self, etype, write=False):
-        """return true if the given entity's type is handled by this adapter
-        if write is true, return true only if it's a RW support
-        """
-        try:
-            wsupport = self.support_entities[etype]
-        except KeyError:
-            return False
-        if write:
-            return wsupport
-        return True
-
-    def support_relation(self, rtype, write=False):
-        """return true if the given relation's type is handled by this adapter
-        if write is true, return true only if it's a RW support
-
-        current implementation return true if the relation is defined into
-        `support_relations` or if it is a final relation of a supported entity
-        type
-        """
-        try:
-            wsupport = self.support_relations[rtype]
-        except KeyError:
-            rschema = self.schema.rschema(rtype)
-            if not rschema.final or rschema.type == 'has_text':
-                return False
-            for etype in rschema.subjects():
-                try:
-                    wsupport = self.support_entities[etype]
-                    break
-                except KeyError:
-                    continue
-            else:
-                return False
-        if write:
-            return wsupport
-        return True
-
     def before_entity_insertion(self, cnx, lid, etype, eid, sourceparams):
         """called by the repository when an eid has been attributed for an
         entity stored here but the entity has not been inserted in the system
--- a/cubicweb/server/sources/native.py	Fri Sep 30 18:24:17 2016 +0200
+++ b/cubicweb/server/sources/native.py	Wed Sep 28 22:17:36 2016 +0200
@@ -505,22 +505,6 @@
             authentifier.set_schema(self.schema)
         clear_cache(self, 'need_fti_indexation')
 
-    def support_entity(self, etype, write=False):
-        """return true if the given entity's type is handled by this adapter
-        if write is true, return true only if it's a RW support
-        """
-        return etype not in NONSYSTEM_ETYPES
-
-    def support_relation(self, rtype, write=False):
-        """return true if the given relation's type is handled by this adapter
-        if write is true, return true only if it's a RW support
-        """
-        if write:
-            return rtype not in NONSYSTEM_RELATIONS
-        # due to current multi-sources implementation, the system source
-        # can't claim not supporting a relation
-        return True  #not rtype == 'content_for'
-
     @statsd_timeit
     def authenticate(self, cnx, login, **kwargs):
         """return CWUser eid for the given login and other authentication