51 Within virtual environment |
51 Within virtual environment |
52 ``````````````````````````` |
52 ``````````````````````````` |
53 |
53 |
54 If you are not administrator of you machine or if you need to play with some |
54 If you are not administrator of you machine or if you need to play with some |
55 specific version of |cubicweb| you can use `virtualenv`_ a tool to create |
55 specific version of |cubicweb| you can use `virtualenv`_ a tool to create |
56 isolated Python environments. Since version 3.9 |cubicweb| is **`virtualenv` |
56 isolated Python environments. |
57 friendly** and won't write any file outside the virtualenv directory. |
|
58 |
57 |
59 - instances are stored in :file:`<VIRTUAL_ENV>/etc/cubicweb.d` |
58 - instances are stored in :file:`<VIRTUAL_ENV>/etc/cubicweb.d` |
60 - temporary files (such as pid file) in :file:`<VIRTUAL_ENV>/var/run/cubicweb` |
59 - temporary files (such as pid file) in :file:`<VIRTUAL_ENV>/var/run/cubicweb` |
61 |
60 |
62 .. _`virtualenv`: http://pypi.python.org/pypi/virtualenv |
61 .. _`virtualenv`: http://pypi.python.org/pypi/virtualenv |
204 |
203 |
205 def possible_configurations(directory): |
204 def possible_configurations(directory): |
206 """return a list of installed configurations in a directory |
205 """return a list of installed configurations in a directory |
207 according to \*-ctl files |
206 according to \*-ctl files |
208 """ |
207 """ |
209 return [name for name in ('repository', 'twisted', 'all-in-one') |
208 return [name for name in ('repository', 'all-in-one') |
210 if exists(join(directory, '%s.conf' % name))] |
209 if exists(join(directory, '%s.conf' % name))] |
211 |
210 |
212 def guess_configuration(directory): |
211 def guess_configuration(directory): |
213 """try to guess the configuration to use for a directory. If multiple |
212 """try to guess the configuration to use for a directory. If multiple |
214 configurations are found, ConfigurationError is raised |
213 configurations are found, ConfigurationError is raised |
326 # log messages format (see logging module documentation for available keys) |
325 # log messages format (see logging module documentation for available keys) |
327 log_format = '%(asctime)s - (%(name)s) %(levelname)s: %(message)s' |
326 log_format = '%(asctime)s - (%(name)s) %(levelname)s: %(message)s' |
328 # the format below can be useful to debug multi thread issues: |
327 # the format below can be useful to debug multi thread issues: |
329 # log_format = '%(asctime)s - [%(threadName)s] (%(name)s) %(levelname)s: %(message)s' |
328 # log_format = '%(asctime)s - [%(threadName)s] (%(name)s) %(levelname)s: %(message)s' |
330 # nor remove appobjects based on unused interface [???] |
329 # nor remove appobjects based on unused interface [???] |
331 cleanup_interface_sobjects = True |
330 cleanup_unused_appobjects = True |
332 |
331 |
333 if (CWDEV and _forced_mode != 'system'): |
332 if (CWDEV and _forced_mode != 'system'): |
334 mode = 'user' |
333 mode = 'user' |
335 _CUBES_DIR = join(CW_SOFTWARE_ROOT, '../cubes') |
334 _CUBES_DIR = join(CW_SOFTWARE_ROOT, '../cubes') |
336 else: |
335 else: |
497 except AttributeError: |
496 except AttributeError: |
498 # deduce cubes from generic __xxx__ attribute |
497 # deduce cubes from generic __xxx__ attribute |
499 try: |
498 try: |
500 gendeps = getattr(pkginfo, key.replace('_cubes', '')) |
499 gendeps = getattr(pkginfo, key.replace('_cubes', '')) |
501 except AttributeError: |
500 except AttributeError: |
502 # bw compat |
501 deps = {} |
503 if hasattr(pkginfo, oldkey): |
|
504 warn('[3.8] cube %s: %s is deprecated, use %s dict' |
|
505 % (cube, oldkey, key), DeprecationWarning) |
|
506 deps = getattr(pkginfo, oldkey) |
|
507 else: |
|
508 deps = {} |
|
509 else: |
502 else: |
510 deps = dict( (x[len('cubicweb-'):], v) |
503 deps = dict( (x[len('cubicweb-'):], v) |
511 for x, v in gendeps.iteritems() |
504 for x, v in gendeps.iteritems() |
512 if x.startswith('cubicweb-')) |
505 if x.startswith('cubicweb-')) |
513 if not isinstance(deps, dict): |
|
514 deps = dict((key, None) for key in deps) |
|
515 warn('[3.8] cube %s should define %s as a dict' % (cube, key), |
|
516 DeprecationWarning) |
|
517 for depcube in deps: |
506 for depcube in deps: |
518 try: |
507 try: |
519 newname = CW_MIGRATION_MAP[depcube] |
508 newname = CW_MIGRATION_MAP[depcube] |
520 except KeyError: |
509 except KeyError: |
521 pass |
510 pass |
938 if not exists(home): |
927 if not exists(home): |
939 raise ConfigurationError('no such instance %s (check it exists with' |
928 raise ConfigurationError('no such instance %s (check it exists with' |
940 ' "cubicweb-ctl list")' % appid) |
929 ' "cubicweb-ctl list")' % appid) |
941 return home |
930 return home |
942 |
931 |
943 MODES = ('common', 'repository', 'Any', 'web') |
932 MODES = ('common', 'repository', 'Any') |
944 MCOMPAT = {'all-in-one': MODES, |
933 MCOMPAT = {'all-in-one': MODES, |
945 'repository': ('common', 'repository', 'Any'), |
934 'repository': ('common', 'repository', 'Any')} |
946 'twisted' : ('common', 'web'),} |
|
947 @classmethod |
935 @classmethod |
948 def accept_mode(cls, mode): |
936 def accept_mode(cls, mode): |
949 #assert mode in cls.MODES, mode |
937 #assert mode in cls.MODES, mode |
950 return mode in cls.MCOMPAT[cls.name] |
938 return mode in cls.MCOMPAT[cls.name] |
951 |
939 |
1187 create_dir(i18ndir) |
1175 create_dir(i18ndir) |
1188 sourcedirs = [join(path, 'i18n') for path in self.cubes_path()] |
1176 sourcedirs = [join(path, 'i18n') for path in self.cubes_path()] |
1189 sourcedirs.append(self.i18n_lib_dir()) |
1177 sourcedirs.append(self.i18n_lib_dir()) |
1190 return i18n.compile_i18n_catalogs(sourcedirs, i18ndir, langs) |
1178 return i18n.compile_i18n_catalogs(sourcedirs, i18ndir, langs) |
1191 |
1179 |
1192 def sendmails(self, msgs): |
1180 def sendmails(self, msgs, fromaddr=None): |
1193 """msgs: list of 2-uple (message object, recipients). Return False |
1181 """msgs: list of 2-uple (message object, recipients). Return False |
1194 if connection to the smtp server failed, else True. |
1182 if connection to the smtp server failed, else True. |
1195 """ |
1183 """ |
1196 server, port = self['smtp-host'], self['smtp-port'] |
1184 server, port = self['smtp-host'], self['smtp-port'] |
|
1185 if fromaddr is None: |
|
1186 fromaddr = '%s <%s>' % (self['sender-name'], self['sender-addr']) |
1197 SMTP_LOCK.acquire() |
1187 SMTP_LOCK.acquire() |
1198 try: |
1188 try: |
1199 try: |
1189 try: |
1200 smtp = SMTP(server, port) |
1190 smtp = SMTP(server, port) |
1201 except Exception as ex: |
1191 except Exception as ex: |
1202 self.exception("can't connect to smtp server %s:%s (%s)", |
1192 self.exception("can't connect to smtp server %s:%s (%s)", |
1203 server, port, ex) |
1193 server, port, ex) |
1204 return False |
1194 return False |
1205 heloaddr = '%s <%s>' % (self['sender-name'], self['sender-addr']) |
|
1206 for msg, recipients in msgs: |
1195 for msg, recipients in msgs: |
1207 try: |
1196 try: |
1208 smtp.sendmail(heloaddr, recipients, msg.as_string()) |
1197 smtp.sendmail(fromaddr, recipients, msg.as_string()) |
1209 except Exception as ex: |
1198 except Exception as ex: |
1210 self.exception("error sending mail to %s (%s)", |
1199 self.exception("error sending mail to %s (%s)", |
1211 recipients, ex) |
1200 recipients, ex) |
1212 smtp.close() |
1201 smtp.close() |
1213 finally: |
1202 finally: |