def get_hook():
request = get_current_request()
try:
site = request.site
search = queryUtility(ICatalogUtility)
except (AttributeError, KeyError):
return
if not search:
return # no search configured
try:
trns = tm(request).get()
except RequestNotFound:
trns = transaction.get()
hook = None
for _hook in trns._after_commit:
if isinstance(_hook[0], CommitHook):
hook = _hook[0]
break
if hook is None:
hook = CommitHook(site, request)
trns.addAfterCommitHook(hook)
return hook
python类get()的实例源码
def client_cleanup(self):
self.job.update_state(BackupJob.State.client_done, BackupJob.State.client_cleanup)
del self.job.client_manifest_data
del self.job.client_manifest_id_str
try:
del self.job.client_key_data
del self.job.client_key_type
except AttributeError:
pass
transaction.get().note('Deleted client keys of job %s' % self.job.id)
transaction.commit()
# TODO delete checkpoints
# TODO do we actually want this? if we leave the cache, the next job has a good chance of rsyncing just a delta
# TODO perhaps a per-client setting, to limit space usage on the client with multiple repositories.
def _add_completed_archive(self):
log.debug('Saving archive metadata to database')
archive = BorgArchive(self.repository, self._repository_key, self._manifest, self.job.archive_name, cache=self._cache)
stats = archive.calc_stats(self._cache)
duration = archive.ts_end - archive.ts
ao = Archive(
id=archive.fpr,
repository=self.job.repository,
name=archive.name,
client=self.job.client,
job=self.job,
nfiles=stats.nfiles,
original_size=stats.osize,
compressed_size=stats.csize,
deduplicated_size=stats.usize,
duration=duration,
timestamp=archive.ts,
timestamp_end=archive.ts_end,
)
self.job.archive = ao
transaction.get().note('Added completed archive %s for job %s' % (ao.id, self.job.id))
transaction.commit()
log.debug('Saved archive metadata')
def test_celery__TransactionAwareTask__delay__5(celery_session_worker, zcml):
"""It allows to run two tasks in a single session."""
auth = zope.component.getUtility(
zope.authentication.interfaces.IAuthentication)
principal = auth.getPrincipal('example.user')
z3c.celery.celery.login_principal(principal)
result1 = get_principal_title_task.delay()
zope.security.management.endInteraction()
principal = auth.getPrincipal('zope.user')
z3c.celery.celery.login_principal(principal)
result2 = get_principal_title_task.delay()
transaction.commit()
assert 'Ben Utzer' == result1.get()
assert 'User' == result2.get()
def invalidate_new_back_revs(event):
''' Invalidate objects that rev_link to us
Catch those objects which newly rev_link us
'''
context = event.object
updated = event.request._updated_uuid_paths
initial = event.request._initial_back_rev_links.get(context.uuid, {})
properties = context.upgrade_properties()
current = {
path: set(simple_path_ids(properties, path))
for path in context.type_info.merged_back_rev
}
for rel, uuids in current.items():
for uuid in uuids.difference(initial.get(rel, ())):
updated[uuid]
def _update_keys(self, model, unique_keys):
keys_set = {(k, v) for k, values in unique_keys.items() for v in values}
existing = {
(key.name, key.value)
for key in model.unique_keys
}
to_remove = existing - keys_set
to_add = keys_set - existing
session = self.DBSession()
for pk in to_remove:
key = session.query(Key).get(pk)
session.delete(key)
for name, value in to_add:
key = Key(rid=model.rid, name=name, value=value)
session.add(key)
return to_add, to_remove
def _update_rels(self, model, links):
session = self.DBSession()
source = model.rid
rels = {(k, uuid.UUID(target)) for k, targets in links.items() for target in targets}
existing = {
(link.rel, link.target_rid)
for link in model.rels
}
to_remove = existing - rels
to_add = rels - existing
for rel, target in to_remove:
link = session.query(Link).get((source, rel, target))
session.delete(link)
for rel, target in to_add:
link = Link(source_rid=source, rel=rel, target_rid=target)
session.add(link)
return to_add, to_remove
def add_transaction_record(session, flush_context, instances):
txn = transaction.get()
# Set data with txn.setExtendedInfo(name, value)
data = txn._extension
record = data.get('_snovault_transaction_record')
if record is not None:
if orm.object_session(record) is None:
# Savepoint rolled back
session.add(record)
# Transaction has already been recorded
return
tid = data['tid'] = uuid.uuid4()
record = TransactionRecord(tid=tid)
data['_snovault_transaction_record'] = record
session.add(record)
def record_transaction_data(session):
txn = transaction.get()
data = txn._extension
if '_snovault_transaction_record' not in data:
return
record = data['_snovault_transaction_record']
# txn.note(text)
if txn.description:
data['description'] = txn.description
# txn.setUser(user_name, path='/') -> '/ user_name'
# Set by pyramid_tm as (userid, '')
if txn.user:
user_path, userid = txn.user.split(' ', 1)
data['userid'] = userid
record.data = {k: v for k, v in data.items() if not k.startswith('_')}
session.add(record)
def set_transaction_isolation_level(session, sqla_txn, connection):
''' Set appropriate transaction isolation level.
Doomed transactions can be read-only.
``transaction.doom()`` must be called before the connection is used.
Othewise assume it is a write which must be REPEATABLE READ.
'''
if connection.engine.url.drivername != 'postgresql':
return
txn = transaction.get()
if not txn.isDoomed():
# connection.execute("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;")
return
data = txn._extension
if 'snapshot_id' in data:
connection.execute(
_set_transaction_snapshot,
snapshot_id=data['snapshot_id'])
else:
connection.execute("SET TRANSACTION READ ONLY;")
def mailer_send(subject="!",
sender=None,
recipients=[],
body=None,
html=None,
attachments=[]):
try:
request = get_current_request()
if sender is None:
sender = request.registry.settings['lac.admin_email']
mailer = get_mailer(request)
message = Message(subject=subject,
sender=sender,
recipients=recipients,
body=body,
html=html)
for attachment in attachments:
attachment = Attachment(attachment.title,
attachment.mimetype,
attachment)
message.attach(attachment)
if transaction.get().status == Status.COMMITTED:
mailer.send_immediately(message)
else:
mailer.send(message)
except Exception:
pass
def set_failure_cause(self, kind, **kwargs):
borgcube.utils.hook.borgcube_job_failure_cause(job=self, kind=kind, kwargs=kwargs)
self.force_state(self.State.failed)
self.failure_cause = {
'kind': kind,
}
self.failure_cause.update(kwargs)
transaction.get().note('Set failure cause of job %s to %s' % (self.id, kind))
transaction.commit()
def action_form_view(self, request):
dotted_path = request.GET.get('class')
cls = ScheduledAction.get_class(dotted_path)
if not cls:
log.error('scheduled_action_form request for %r which is not a schedulable action', dotted_path)
return HttpResponseBadRequest()
return HttpResponse(cls.Form().as_table())
def delete_view(self, request):
if request.method == 'POST':
data_root().schedules.remove(self.schedule)
transaction.get().note('Deleted schedule %s' % self.schedule.oid)
transaction.commit()
return self.parent.redirect_to()
def add_view(self, request):
data = request.POST or None
client_form = Client.Form(data)
connection_form = RshClientConnection.Form(data)
if data and client_form.is_valid() and connection_form.is_valid():
connection = RshClientConnection(**connection_form.cleaned_data)
client = Client(connection=connection, **client_form.cleaned_data)
transaction.get().note('Added client %s' % client.hostname)
transaction.commit()
return self.redirect_to()
return self.render(request, 'core/client/add.html', {
'client_form': client_form,
'connection_form': connection_form,
})
def add_view(self, request):
client = self.parent.client
data = request.POST or None
form = JobConfigForm(data=data)
advanced_form = JobConfigForm.AdvancedForm(data=data)
if data and form.is_valid() and advanced_form.is_valid():
config = form.cleaned_data
config.update(advanced_form.cleaned_data)
config['paths'] = config.get('paths', '').split('\n')
config['excludes'] = [s for s in config.get('excludes', '').split('\n') if s]
repository = config.pop('repository')
job_config = BackupConfig(client=client, repository=repository, label=config['label'])
job_config._update(config)
client.job_configs.append(job_config)
transaction.get().note('Added job config to client %s' % client.hostname)
transaction.commit()
# TODO StringListValidator
# TODO Pattern validation
# TODO fancy pattern editor with test area
return self[job_config.oid].redirect_to()
return self.render(request, 'core/client/config_add.html', {
'form': form,
'advanced_form': advanced_form,
})
def edit_view(self, request):
client = self.config.client
job_config = self.config
data = request.POST or None
job_config._p_activate()
initial_data = dict(job_config.__dict__)
initial_data['paths'] = '\n'.join(initial_data['paths'])
initial_data['excludes'] = '\n'.join(initial_data['excludes'])
form = JobConfigForm(data=data, initial=initial_data)
advanced_form = JobConfigForm.AdvancedForm(data=data, initial=initial_data)
if data and form.is_valid() and advanced_form.is_valid():
config = form.cleaned_data
config.update(advanced_form.cleaned_data)
config['paths'] = config.get('paths', '').split('\n')
config['excludes'] = [s for s in config.get('excludes', '').split('\n') if s]
job_config._update(config)
# TODO StringListValidator
# TODO Pattern validation
# TODO fancy pattern editor with test area
transaction.get().note('Edited job config %s of client %s' % (job_config.oid, client.hostname))
transaction.commit()
return self.redirect_to()
return self.render(request, 'core/client/config_edit.html', {
'client': client,
'form': form,
'advanced_form': advanced_form,
'job_config': job_config,
})
def delete_view(self, request):
client = self.parent.parent.client
if request.method == 'POST':
client.job_configs.remove(self.config)
# Could just leave it there, but likely not the intention behind clicking (delete).
for schedule in data_root().schedules:
for action in list(schedule.actions):
if getattr(action, 'job_config', None) == self.config:
schedule.actions.remove(action)
transaction.get().note('Deleted job config %s from client %s' % (self.config.oid, client.hostname))
transaction.commit()
return self.redirect_to()
def add_view(self, request):
data = request.POST or None
form = RetentionPolicy.Form(data)
if data and form.is_valid():
policy = RetentionPolicy(**form.cleaned_data)
prune_root().policies.append(policy)
transaction.get().note('Added prune retention policy %s' % policy.name)
transaction.commit()
# return redirect(prune_retention_policies)
return self.render(request, 'core/prune/policy_add.html', {
'form': form,
'title': _('Add retention policy'),
'submit': _('Add retention policy'),
})
def view(self, request):
data = request.POST or None
self.policy._p_activate()
form = RetentionPolicy.Form(data, initial=self.policy.__dict__)
if data and form.is_valid():
self.policy._update(form.cleaned_data)
transaction.get().note('Edited prune retention policy %s' % self.policy.oid)
transaction.commit()
return self.parent.redirect_to()
return self.render(request, 'core/prune/policy_add.html', {
'form': form,
'title': _('Edit retention policy'),
'submit': _('Save changes'),
})
def add_view(self, request):
data = request.POST or None
form = PruneConfig.Form(data)
if data and form.is_valid():
config = PruneConfig(**form.cleaned_data)
prune_root().configs.append(config)
transaction.get().note('Added prune config %s' % config.name)
transaction.commit()
return self.redirect_to()
return self.render(request, 'core/prune/config_add.html', {
'form': form,
'title': _('Add prune configuration'),
'submit': _('Add prune configuration'),
})
def view(self, request):
data = request.POST or None
form = PruneConfig.Form(data, initial=self.config.__dict__)
if data and form.is_valid():
self.config._update(form.cleaned_data)
transaction.get().note('Edited prune config %s' % self.config.oid)
transaction.commit()
return self.parent.redirect_to()
return self.render(request, 'core/prune/config_add.html', {
'form': form,
'title': _('Edit prune configuration'),
'submit': _('Edit prune configuration'),
})
def add_view(self, request):
data = request.POST or None
repository_form = Repository.Form(data)
if data and repository_form.is_valid():
repository = Repository(**repository_form.cleaned_data)
data_root().repositories.append(repository)
transaction.get().note('Added repository %s' % repository.name)
transaction.commit()
return self.redirect_to()
return self.render(request, 'core/repository/add.html', {
'repository_form': repository_form,
})
def edit_view(self, request):
data = request.POST or None
repository = self.repository
repository._p_activate()
repository_form = Repository.Form(data, initial=repository.__dict__)
if data and repository_form.is_valid():
repository._update(repository_form.cleaned_data)
transaction.get().note('Edited repository %s' % repository.oid)
transaction.commit()
return self.redirect_to()
return self.render(request, 'core/repository/edit.html', {
'repository_form': repository_form,
})
def add_view(self, request):
data = request.POST or None
config_form = CheckConfig.Form(data)
if data and config_form.is_valid():
config = CheckConfig(self.repository, **config_form.cleaned_data)
self.repository.job_configs.append(config)
transaction.get().note('Added check config to repository %s' % self.repository.oid)
transaction.commit()
return self.parent.redirect_to()
return self.render(request, 'core/repository/config_add.html', {
'form': config_form,
})
def delete_view(self, request):
if request.method == 'POST':
repository = self.parent.repository
repository.job_configs.remove(self.config)
transaction.get().note('Deleted check config %s from repository %s' % (self.config.oid, repository.oid))
transaction.commit()
return self.parent.parent.redirect_to()
def __init__(self):
self.metrics = PersistentList()
from .builtin_metrics import ArchiveCount, TotalData, BackupsToday
self.metrics.append(ArchiveCount())
self.metrics.append(TotalData())
self.metrics.append(BackupsToday())
transaction.get().note('web: added default metrics')
transaction.commit()
def synthesize_crypto(job):
with open_repository(job.repository) as repository:
if bin_to_hex(repository.id) != job.repository.repository_id:
raise RepositoryIDMismatch(bin_to_hex(repository.id), job.repository.repository_id)
manifest, key = Manifest.load(repository)
client_key = synthesize_client_key(key, repository)
if not isinstance(client_key, PlaintextKey):
job.client_key_data = client_key.get_key_data()
job.client_key_type = client_key.synthetic_type
client_manifest = SyntheticManifest(client_key, repository.id)
job.client_manifest_data = bin_to_hex(client_manifest.write())
job.client_manifest_id_str = client_manifest.id_str
transaction.get().note('Synthesized crypto for job %s' % job.id)
transaction.commit()
def create_job(self):
job = BackupJob(
repository=self.repository,
client=self.client,
config=self,
)
transaction.get().note('Created backup job from check config %s on client %s' % (self.oid, self.client.hostname))
log.info('Created job for client %s, job config %s', self.client.hostname, self.oid)
def create_job(self):
job = PruneJob(config=self)
transaction.get().note('Created prune job from config %s' % self.oid)
log.info('Created prune job for config %s', self.oid)