Repository: WeblateOrg/weblate

Issue:
Credit terminology entries to adding user
### Describe the issue

The name is "None" and without any profile.. Since the name does not ring anything for a real person, I take it as some kind of AI-like system user.

And it has gone rogue for quite some time. It adds new items to the glossary no one asked for, sometimes acceptable, but mostly lots of nonsense duplicates.

Below are new addition made by it; most are parts of scripting codes (underscores) and 3 are exact duplicates.

https://hosted.weblate.org/browse/learn-gdscript-from-zero/glossary/tr/?q=state:%3Ctranslated

![new glossary item](https://github.com/WeblateOrg/weblate/assets/1812105/8190164a-78c5-4c50-8afb-0008526240ff)

https://hosted.weblate.org/translate/learn-gdscript-from-zero/glossary/tr/?checksum=8ed571e7e2730eb8&q=state%3A%3Ctranslated

![added by None system user](https://github.com/WeblateOrg/weblate/assets/1812105/9f68f93f-dcf9-4a66-aa7d-b6b964bc4dee)


I reported a similar issue before that if I try to delete duplicates, this None would revive them. I haven't heard about that from you yet, so you may take this as a complimentary issue and treat them both equal in fixing the None user.

https://github.com/WeblateOrg/weblate/issues/9593

Please fix the behaviour of this system user asap.

### I already tried

- [X] I've read and searched [the documentation](https://docs.weblate.org/).
- [X] I've searched for similar issues in this repository.

### Steps to reproduce the behavior

1. Just wait because there is no timer for this behavior
   - and then the None will add new items sooner or later, then you will be notified in the daily digest if set.


### Expected behavior

The None user should either not
 - add new items into the glossary
 - or have the mind not to add duplicate words, and/or code parts

### Screenshots

related screenshots are given under their respective links above

### Exception traceback

_No response_

### How do you run Weblate?

weblate.org service

### Weblate versions

_No response_

### Weblate deploy checks

_No response_

### Additional context

_No response_


Discussion:
There is no AI in this, it's just operations which can't be accounted to any user. See also https://github.com/WeblateOrg/weblate/issues/3009.

In this particular case, the term was added upon commit to the language because of the `terminology` flag. And it is there four times because somebody added it there four times: https://hosted.weblate.org/translate/learn-gdscript-from-zero/glossary/en/?checksum=241ff434c9eab98e#others
Alright then, one mystery is solved. So, these nonsense additions are actually made by some real user but directly into the main language, here English.

I will try to delete these nonsense/duplicate strings from there and see what happens.
I am now traversing the English glossary and I can see there are items I added for my language, Turkish.

I thought adding new items to the glossary will only go to my selected/current language's glossary.

But now it is clear it goes back to the main language, and then propagates to other languages.

@nijel , do you know if there is/was any work about separating these two behaviors? not to propagate to other languages?
This issue has been marked as a question by a Weblate team member. Why? Because it belongs more to the professional [Weblate Care](https://care.weblate.org/) or community [Discussions](https://github.com/WeblateOrg/weblate/discussions) than here. We strive to answer these reasonably fast here, too, but [purchasing the support subscription](https://weblate.org/support/) is more responsible and faster for your business. And it makes Weblate stronger as well. Thanks!

In case your question is already answered, [making a donation](https://weblate.org/donate/) is the right way to say thank you!

Resolving patch:
diff --git a/weblate/trans/models/translation.py b/weblate/trans/models/translation.py
--- a/weblate/trans/models/translation.py
+++ b/weblate/trans/models/translation.py
@@ -1374,7 +1374,6 @@ def add_unit(  # noqa: C901
         auto_context: bool = False,
         is_batch_update: bool = False,
         skip_existing: bool = False,
-        sync_terminology: bool = True,
         state: int | None = None,
     ):
         if isinstance(source, list):
@@ -1382,12 +1381,21 @@ def add_unit(  # noqa: C901
         user = request.user if request else None
         component = self.component
         if self.is_source:
-            translations = [self]
-            translations.extend(
-                component.translation_set.exclude(id=self.id).select_related("language")
+            translations = (
+                self,
+                *component.translation_set.exclude(id=self.id).select_related(
+                    "language"
+                ),
+            )
+        elif component.is_glossary and "terminology" in Flags(extra_flags):
+            translations = (
+                component.source_translation,
+                *component.translation_set.exclude(
+                    id=component.source_translation.id
+                ).select_related("language"),
             )
         else:
-            translations = [component.source_translation, self]
+            translations = (component.source_translation, self)
         has_template = component.has_template()
         source_unit = None
         result = None
@@ -1504,8 +1512,6 @@ def add_unit(  # noqa: C901
                 component.update_variants(
                     updated_units=Unit.objects.filter(pk__in=unit_ids)
                 )
-            if sync_terminology:
-                component.schedule_sync_terminology()
             component.invalidate_cache()
             component_post_update.send(sender=self.__class__, component=component)
             self.was_new = 1
@@ -1601,7 +1607,6 @@ def sync_terminology(self):
                 "",
                 is_batch_update=True,
                 skip_existing=True,
-                sync_terminology=False,
             )
             self.was_new += 1
         self.notify_new(None)


Test patch:
diff --git a/weblate/glossary/tests.py b/weblate/glossary/tests.py
--- a/weblate/glossary/tests.py
+++ b/weblate/glossary/tests.py
@@ -315,26 +315,43 @@ def test_get_single(self):
             {"thank"},
         )
 
-    def test_add(self):
-        """Test for adding term from translate page."""
+    def do_add_unit(self, **kwargs):
         unit = self.get_unit("Thank you for using Weblate.")
         # Add term
         response = self.client.post(
             reverse("js-add-glossary", kwargs={"unit_id": unit.pk}),
-            {"source": "source", "target": "překlad", "translation": self.glossary.pk},
+            {
+                "source": "source",
+                "target": "překlad",
+                "translation": self.glossary.pk,
+                **kwargs,
+            },
         )
         content = json.loads(response.content.decode())
         self.assertEqual(content["responseCode"], 200)
 
+    def test_add(self):
+        """Test for adding term from translate page."""
+        start = Unit.objects.count()
+        self.do_add_unit()
+        # Should be added to the source and translation only
+        self.assertEqual(Unit.objects.count(), start + 2)
+
+    def test_add_terminology(self):
+        start = Unit.objects.count()
+        self.do_add_unit(terminology=1)
+        # Should be added to all languages
+        self.assertEqual(Unit.objects.count(), start + 4)
+
     def test_add_duplicate(self):
-        self.test_add()
-        self.test_add()
+        self.do_add_unit()
+        self.do_add_unit()
 
     def test_terminology(self):
         start = Unit.objects.count()
 
         # Add single term
-        self.test_add()
+        self.do_add_unit()
 
         # Verify it has been added to single language (+ source)
         unit = self.glossary_component.source_translation.unit_set.get(source="source")