def notify_change(change_id): from weblate.trans.models import Change from weblate.accounts.notifications import ( notify_merge_failure, notify_parse_error, notify_new_string, notify_new_contributor, notify_new_suggestion, notify_new_comment, notify_new_translation, notify_new_language, ) change = Change.objects.get(pk=change_id) if change.action in (Change.ACTION_FAILED_MERGE, Change.ACTION_FAILED_REBASE): notify_merge_failure(change) elif change.action == Change.ACTION_PARSE_ERROR: notify_parse_error(change) elif change.action == Change.ACTION_NEW_STRING: notify_new_string(change) elif change.action == Change.ACTION_NEW_CONTRIBUTOR: notify_new_contributor(change) elif change.action == Change.ACTION_SUGGESTION: notify_new_suggestion(change) elif change.action == Change.ACTION_COMMENT: notify_new_comment(change) elif change.action in Change.ACTIONS_CONTENT: notify_new_translation(change) elif change.action in (Change.ACTION_ADDED_LANGUAGE, Change.ACTION_REQUESTED_LANGUAGE): notify_new_language(change)
def test_notify_new_translation(self): unit = self.get_unit() unit2 = self.get_translation().unit_set.get( source='Thank you for using Weblate.') notify_new_translation(unit, unit2, self.second_user()) # Check mail self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, '[Weblate] New translation in Test/Test - Czech')
def test_notify_new_translation(self): change = Change( unit=self.get_unit(), user=self.second_user(), old='', ) notify_new_translation(change) # Check mail self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, '[Weblate] New translation in Test/Test - Czech')
def test_notify_new_translation(self): unit = self.get_unit() unit2 = self.get_translation().unit_set.get( source='Thank you for using Weblate.' ) notify_new_translation( unit, unit2, self.second_user() ) # Check mail self.assertEqual(len(mail.outbox), 1) self.assertEqual( mail.outbox[0].subject, '[Weblate] New translation in Test/Test - Czech' )
def save_backend(self, request, propagate=True, gen_change=True, change_action=None, user=None): """ Stores unit to backend. Optional user parameters defines authorship of a change. """ # For case when authorship specified, use user from request if user is None or user.is_anonymous: user = request.user # Update lock timestamp self.update_lock(request, user, change_action) # Commit possible previous changes by other author self.translation.commit_pending(request, get_author_name(user)) # Return if there was no change # We have to explicitly check for fuzzy flag change on monolingual # files, where we handle it ourselves without storing to backend if (self.old_unit.fuzzy == self.fuzzy and self.old_unit.target == self.target): # Propagate if we should if propagate: self.propagate(request, change_action) return False # Propagate to other projects # This has to be done before changing source/content_hash for template if propagate: self.propagate(request, change_action) if self.translation.is_template(): self.source = self.target self.content_hash = calculate_hash(self.source, self.context) # Unit is pending for write self.pending = True # Update translated flag (not fuzzy and at least one transltion) self.translated = ( not self.fuzzy and bool(max(self.get_target_plurals())) ) # Save updated unit to database self.save(backend=True) # Update translation stats old_translated = self.translation.translated if change_action != Change.ACTION_UPLOAD: self.translation.update_stats() self.translation.store_hash() # Notify subscribed users about new translation notify_new_translation(self, self.old_unit, user) # Update user stats user.profile.translated += 1 user.profile.save() # Generate Change object for this change if gen_change: self.generate_change(request, user, self.old_unit, change_action) # Force commiting on completing translation if (old_translated < self.translation.translated and self.translation.translated == self.translation.total): self.translation.commit_pending(request) Change.objects.create( translation=self.translation, action=Change.ACTION_COMPLETE, user=user, author=user ) # Update related source strings if working on a template if self.translation.is_template(): self.update_source_units(self.old_unit.source, user) return True
def save_backend(self, request, propagate=True, change_action=None, user=None): """ Stores unit to backend. Optional user parameters defines authorship of a change. This should be always called in a trasaction with updated unit locked for update. """ # For case when authorship specified, use user from request if user is None or (user.is_anonymous and request): user = request.user # Commit possible previous changes on this unit if self.pending: try: change = self.change_set.content().order_by('-timestamp')[0] except IndexError as error: # This is probably bug in the change data, fallback by using # any change entry report_error(error, request) change = self.change_set.all().order_by('-timestamp')[0] if change.author_id != request.user.id: self.translation.commit_pending('pending unit', request) # Propagate to other projects # This has to be done before changing source/content_hash for template if propagate: self.propagate(request, change_action) # Return if there was no change # We have to explicitly check for fuzzy flag change on monolingual # files, where we handle it ourselves without storing to backend if (self.old_unit.state == self.state and self.old_unit.target == self.target): return False if self.translation.is_template: self.source = self.target self.content_hash = calculate_hash(self.source, self.context) # Unit is pending for write self.pending = True # Update translated flag (not fuzzy and at least one translation) translation = bool(max(self.get_target_plurals())) if self.state >= STATE_TRANSLATED and not translation: self.state = STATE_EMPTY elif self.state == STATE_EMPTY and translation: self.state = STATE_TRANSLATED # Save updated unit to database self.save() # Run source checks self.source_info.run_checks(unit=self) # Generate Change object for this change self.generate_change(request, user, change_action) if change_action not in (Change.ACTION_UPLOAD, Change.ACTION_AUTO): # Update translation stats self.translation.invalidate_cache() # Update user stats user.profile.translated += 1 user.profile.save() # Notify subscribed users about new translation from weblate.accounts.notifications import notify_new_translation notify_new_translation(self, self.old_unit, user) # Update related source strings if working on a template if self.translation.is_template: self.update_source_units(self.old_unit.source, user) return True
def save_backend(self, request, propagate=True, gen_change=True, change_action=None, user=None): """ Stores unit to backend. Optional user parameters defines authorship of a change. """ # For case when authorship specified, use user from request if user is None or user.is_anonymous: user = request.user # Update lock timestamp self.update_lock(request, user, change_action) # Store to backend try: (saved, pounit) = self.translation.update_unit(self, request, user) except FileLockException: self.log_error('failed to lock backend for %s!', self) messages.error( request, _('Failed to store message in the backend, ' 'lock timeout occurred!')) return False # Handle situation when backend did not find the message if pounit is None: self.log_error('message %s disappeared!', self) messages.error( request, _('Message not found in backend storage, ' 'it is probably corrupted.')) # Try reloading from backend self.translation.check_sync(True) return False # Return if there was no change # We have to explicitly check for fuzzy flag change on monolingual # files, where we handle it ourselves without storing to backend if (not saved and self.old_unit.fuzzy == self.fuzzy and self.old_unit.target == self.target): # Propagate if we should if propagate: self.propagate(request, change_action) return False # Update translated flag self.translated = pounit.is_translated() # Update comments as they might have been changed (eg, fuzzy flag # removed) self.flags = pounit.get_flags() if self.translation.is_template(): self.source = self.target self.content_hash = calculate_hash(self.source, self.context) # Save updated unit to database self.save(backend=True) # Update translation stats old_translated = self.translation.translated if change_action != Change.ACTION_UPLOAD: self.translation.update_stats() # Notify subscribed users about new translation notify_new_translation(self, self.old_unit, user) # Update user stats user.profile.translated += 1 user.profile.save() # Generate Change object for this change if gen_change: self.generate_change(request, user, self.old_unit, change_action) # Force commiting on completing translation if (old_translated < self.translation.translated and self.translation.translated == self.translation.total): self.translation.commit_pending(request) Change.objects.create(translation=self.translation, action=Change.ACTION_COMPLETE, user=user, author=user) # Update related source strings if working on a template if self.translation.is_template(): self.update_source_units(self.old_unit.source) # Propagate to other projects if propagate: self.propagate(request, change_action) return True
def save_backend(self, request, propagate=True, gen_change=True, change_action=None, user=None): """ Stores unit to backend. Optional user parameters defines authorship of a change. This should be always called in a trasaction with updated unit locked for update. """ # For case when authorship specified, use user from request if user is None or (user.is_anonymous and request): user = request.user # Commit possible previous changes on this unit if self.pending: change = self.change_set.content().order_by('-timestamp')[0] if change.author_id != request.user.id: self.translation.commit_pending(request) # Return if there was no change # We have to explicitly check for fuzzy flag change on monolingual # files, where we handle it ourselves without storing to backend if (self.old_unit.state == self.state and self.old_unit.target == self.target): # Propagate if we should if propagate: self.propagate(request, change_action) return False # Propagate to other projects # This has to be done before changing source/content_hash for template if propagate: self.propagate(request, change_action) if self.translation.is_template: self.source = self.target self.content_hash = calculate_hash(self.source, self.context) # Unit is pending for write self.pending = True # Update translated flag (not fuzzy and at least one translation) translation = bool(max(self.get_target_plurals())) if self.state == STATE_TRANSLATED and not translation: self.state = STATE_EMPTY elif self.state == STATE_EMPTY and translation: self.state = STATE_TRANSLATED # Save updated unit to database self.save(backend=True) old_translated = self.translation.stats.translated if change_action not in (Change.ACTION_UPLOAD, Change.ACTION_AUTO): # Update translation stats self.translation.invalidate_cache() # Update user stats user.profile.translated += 1 user.profile.save() # Notify subscribed users about new translation from weblate.accounts.notifications import notify_new_translation notify_new_translation(self, self.old_unit, user) # Generate Change object for this change if gen_change: self.generate_change(request, user, change_action) # Force commiting on completing translation translated = self.translation.stats.translated if (old_translated < translated and translated == self.translation.stats.all): Change.objects.create( translation=self.translation, action=Change.ACTION_COMPLETE, user=user, author=user ) self.translation.commit_pending(request) # Update related source strings if working on a template if self.translation.is_template: self.update_source_units(self.old_unit.source, user) return True
def save_backend(self, request, propagate=True, gen_change=True, change_action=None, user=None): """ Stores unit to backend. Optional user parameters defines authorship of a change. This should be always called in a trasaction with updated unit locked for update. """ # For case when authorship specified, use user from request if user is None or user.is_anonymous: user = request.user # Commit possible previous changes on this unit if self.pending: change = self.change_set.content().order_by('-timestamp')[0] if change.author_id != request.user.id: self.translation.commit_pending(request) # Return if there was no change # We have to explicitly check for fuzzy flag change on monolingual # files, where we handle it ourselves without storing to backend if (self.old_unit.state == self.state and self.old_unit.target == self.target): # Propagate if we should if propagate: self.propagate(request, change_action) return False # Propagate to other projects # This has to be done before changing source/content_hash for template if propagate: self.propagate(request, change_action) if self.translation.is_template: self.source = self.target self.content_hash = calculate_hash(self.source, self.context) # Unit is pending for write self.pending = True # Update translated flag (not fuzzy and at least one translation) translation = bool(max(self.get_target_plurals())) if self.state == STATE_TRANSLATED and not translation: self.state = STATE_EMPTY elif self.state == STATE_EMPTY and translation: self.state = STATE_TRANSLATED # Save updated unit to database self.save(backend=True) old_translated = self.translation.stats.translated if change_action not in (Change.ACTION_UPLOAD, Change.ACTION_AUTO): # Update translation stats self.translation.invalidate_cache() # Update user stats user.profile.translated += 1 user.profile.save() # Notify subscribed users about new translation notify_new_translation(self, self.old_unit, user) # Generate Change object for this change if gen_change: self.generate_change(request, user, change_action) # Force commiting on completing translation translated = self.translation.stats.translated if (old_translated < translated and translated == self.translation.stats.all): Change.objects.create(translation=self.translation, action=Change.ACTION_COMPLETE, user=user, author=user) self.translation.commit_pending(request) # Update related source strings if working on a template if self.translation.is_template: self.update_source_units(self.old_unit.source, user) return True
def save_backend(self, request, propagate=True, gen_change=True, change_action=None, user=None): """ Stores unit to backend. Optional user parameters defines authorship of a change. """ # For case when authorship specified, use user from request if user is None or user.is_anonymous: user = request.user # Update lock timestamp self.update_lock(request, user, change_action) # Store to backend try: (saved, pounit) = self.translation.update_unit(self, request, user) except FileLockException: self.log_error('failed to lock backend for %s!', self) messages.error( request, _( 'Failed to store message in the backend, ' 'lock timeout occurred!' ) ) return False # Handle situation when backend did not find the message if pounit is None: self.log_error('message %s disappeared!', self) messages.error( request, _( 'Message not found in backend storage, ' 'it is probably corrupted.' ) ) # Try reloading from backend self.translation.check_sync(True) return False # Return if there was no change # We have to explicitly check for fuzzy flag change on monolingual # files, where we handle it ourselves without storing to backend if (not saved and self.old_unit.fuzzy == self.fuzzy and self.old_unit.target == self.target): # Propagate if we should if propagate: self.propagate(request, change_action) return False # Update translated flag self.translated = pounit.is_translated() # Update comments as they might have been changed (eg, fuzzy flag # removed) self.flags = pounit.get_flags() if self.translation.is_template(): self.source = self.target self.content_hash = calculate_hash(self.source, self.context) # Save updated unit to database self.save(backend=True) # Update translation stats old_translated = self.translation.translated if change_action != Change.ACTION_UPLOAD: self.translation.update_stats() # Notify subscribed users about new translation notify_new_translation(self, self.old_unit, user) # Update user stats user.profile.translated += 1 user.profile.save() # Generate Change object for this change if gen_change: self.generate_change(request, user, self.old_unit, change_action) # Force commiting on completing translation if (old_translated < self.translation.translated and self.translation.translated == self.translation.total): self.translation.commit_pending(request) Change.objects.create( translation=self.translation, action=Change.ACTION_COMPLETE, user=user, author=user ) # Update related source strings if working on a template if self.translation.is_template(): self.update_source_units(self.old_unit.source) # Propagate to other projects if propagate: self.propagate(request, change_action) return True