mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	models: Extract zerver.models.bots.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							27c0b507af
						
					
				
				
					commit
					1f1b2f9a68
				
			@@ -41,8 +41,8 @@ from zerver.models import (
 | 
			
		||||
    Subscription,
 | 
			
		||||
    UserGroupMembership,
 | 
			
		||||
    UserProfile,
 | 
			
		||||
    get_bot_services,
 | 
			
		||||
)
 | 
			
		||||
from zerver.models.bots import get_bot_services
 | 
			
		||||
from zerver.models.realms import get_fake_email_domain
 | 
			
		||||
from zerver.models.users import (
 | 
			
		||||
    active_non_guest_user_ids,
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,8 @@ from zerver.lib.outgoing_http import OutgoingSession
 | 
			
		||||
from zerver.lib.queue import retry_event
 | 
			
		||||
from zerver.lib.topic import get_topic_from_message_info
 | 
			
		||||
from zerver.lib.url_encoding import near_message_url
 | 
			
		||||
from zerver.models import GENERIC_INTERFACE, SLACK_INTERFACE, Realm, Service, UserProfile
 | 
			
		||||
from zerver.models import Realm, Service, UserProfile
 | 
			
		||||
from zerver.models.bots import GENERIC_INTERFACE, SLACK_INTERFACE
 | 
			
		||||
from zerver.models.clients import get_client
 | 
			
		||||
from zerver.models.users import get_user_profile_by_id
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
from typing import Dict, List, Tuple, TypeVar, Union
 | 
			
		||||
from typing import List, Tuple, TypeVar, Union
 | 
			
		||||
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.db.backends.base.base import BaseDatabaseWrapper
 | 
			
		||||
@@ -13,6 +13,9 @@ from zerver.lib.cache import (
 | 
			
		||||
    realm_alert_words_automaton_cache_key,
 | 
			
		||||
    realm_alert_words_cache_key,
 | 
			
		||||
)
 | 
			
		||||
from zerver.models.bots import BotConfigData as BotConfigData
 | 
			
		||||
from zerver.models.bots import BotStorageData as BotStorageData
 | 
			
		||||
from zerver.models.bots import Service as Service
 | 
			
		||||
from zerver.models.clients import Client as Client
 | 
			
		||||
from zerver.models.custom_profile_fields import CustomProfileField as CustomProfileField
 | 
			
		||||
from zerver.models.custom_profile_fields import CustomProfileFieldValue as CustomProfileFieldValue
 | 
			
		||||
@@ -130,83 +133,6 @@ def query_for_ids(
 | 
			
		||||
    return query
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Interfaces for services
 | 
			
		||||
# They provide additional functionality like parsing message to obtain query URL, data to be sent to URL,
 | 
			
		||||
# and parsing the response.
 | 
			
		||||
GENERIC_INTERFACE = "GenericService"
 | 
			
		||||
SLACK_INTERFACE = "SlackOutgoingWebhookService"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# A Service corresponds to either an outgoing webhook bot or an embedded bot.
 | 
			
		||||
# The type of Service is determined by the bot_type field of the referenced
 | 
			
		||||
# UserProfile.
 | 
			
		||||
#
 | 
			
		||||
# If the Service is an outgoing webhook bot:
 | 
			
		||||
# - name is any human-readable identifier for the Service
 | 
			
		||||
# - base_url is the address of the third-party site
 | 
			
		||||
# - token is used for authentication with the third-party site
 | 
			
		||||
#
 | 
			
		||||
# If the Service is an embedded bot:
 | 
			
		||||
# - name is the canonical name for the type of bot (e.g. 'xkcd' for an instance
 | 
			
		||||
#   of the xkcd bot); multiple embedded bots can have the same name, but all
 | 
			
		||||
#   embedded bots with the same name will run the same code
 | 
			
		||||
# - base_url and token are currently unused
 | 
			
		||||
class Service(models.Model):
 | 
			
		||||
    name = models.CharField(max_length=UserProfile.MAX_NAME_LENGTH)
 | 
			
		||||
    # Bot user corresponding to the Service.  The bot_type of this user
 | 
			
		||||
    # determines the type of service.  If non-bot services are added later,
 | 
			
		||||
    # user_profile can also represent the owner of the Service.
 | 
			
		||||
    user_profile = models.ForeignKey(UserProfile, on_delete=CASCADE)
 | 
			
		||||
    base_url = models.TextField()
 | 
			
		||||
    token = models.TextField()
 | 
			
		||||
    # Interface / API version of the service.
 | 
			
		||||
    interface = models.PositiveSmallIntegerField(default=1)
 | 
			
		||||
 | 
			
		||||
    # Valid interfaces are {generic, zulip_bot_service, slack}
 | 
			
		||||
    GENERIC = 1
 | 
			
		||||
    SLACK = 2
 | 
			
		||||
 | 
			
		||||
    ALLOWED_INTERFACE_TYPES = [
 | 
			
		||||
        GENERIC,
 | 
			
		||||
        SLACK,
 | 
			
		||||
    ]
 | 
			
		||||
    # N.B. If we used Django's choice=... we would get this for free (kinda)
 | 
			
		||||
    _interfaces: Dict[int, str] = {
 | 
			
		||||
        GENERIC: GENERIC_INTERFACE,
 | 
			
		||||
        SLACK: SLACK_INTERFACE,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def interface_name(self) -> str:
 | 
			
		||||
        # Raises KeyError if invalid
 | 
			
		||||
        return self._interfaces[self.interface]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_bot_services(user_profile_id: int) -> List[Service]:
 | 
			
		||||
    return list(Service.objects.filter(user_profile_id=user_profile_id))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_service_profile(user_profile_id: int, service_name: str) -> Service:
 | 
			
		||||
    return Service.objects.get(user_profile_id=user_profile_id, name=service_name)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BotStorageData(models.Model):
 | 
			
		||||
    bot_profile = models.ForeignKey(UserProfile, on_delete=CASCADE)
 | 
			
		||||
    key = models.TextField(db_index=True)
 | 
			
		||||
    value = models.TextField()
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        unique_together = ("bot_profile", "key")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BotConfigData(models.Model):
 | 
			
		||||
    bot_profile = models.ForeignKey(UserProfile, on_delete=CASCADE)
 | 
			
		||||
    key = models.TextField(db_index=True)
 | 
			
		||||
    value = models.TextField()
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        unique_together = ("bot_profile", "key")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AlertWord(models.Model):
 | 
			
		||||
    # Realm isn't necessary, but it's a nice denormalization.  Users
 | 
			
		||||
    # never move to another realm, so it's static, and having Realm
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										82
									
								
								zerver/models/bots.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								zerver/models/bots.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
from typing import Dict, List
 | 
			
		||||
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.db.models import CASCADE
 | 
			
		||||
 | 
			
		||||
from zerver.models.users import UserProfile
 | 
			
		||||
 | 
			
		||||
# Interfaces for services
 | 
			
		||||
# They provide additional functionality like parsing message to obtain query URL, data to be sent to URL,
 | 
			
		||||
# and parsing the response.
 | 
			
		||||
GENERIC_INTERFACE = "GenericService"
 | 
			
		||||
SLACK_INTERFACE = "SlackOutgoingWebhookService"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# A Service corresponds to either an outgoing webhook bot or an embedded bot.
 | 
			
		||||
# The type of Service is determined by the bot_type field of the referenced
 | 
			
		||||
# UserProfile.
 | 
			
		||||
#
 | 
			
		||||
# If the Service is an outgoing webhook bot:
 | 
			
		||||
# - name is any human-readable identifier for the Service
 | 
			
		||||
# - base_url is the address of the third-party site
 | 
			
		||||
# - token is used for authentication with the third-party site
 | 
			
		||||
#
 | 
			
		||||
# If the Service is an embedded bot:
 | 
			
		||||
# - name is the canonical name for the type of bot (e.g. 'xkcd' for an instance
 | 
			
		||||
#   of the xkcd bot); multiple embedded bots can have the same name, but all
 | 
			
		||||
#   embedded bots with the same name will run the same code
 | 
			
		||||
# - base_url and token are currently unused
 | 
			
		||||
class Service(models.Model):
 | 
			
		||||
    name = models.CharField(max_length=UserProfile.MAX_NAME_LENGTH)
 | 
			
		||||
    # Bot user corresponding to the Service.  The bot_type of this user
 | 
			
		||||
    # determines the type of service.  If non-bot services are added later,
 | 
			
		||||
    # user_profile can also represent the owner of the Service.
 | 
			
		||||
    user_profile = models.ForeignKey(UserProfile, on_delete=CASCADE)
 | 
			
		||||
    base_url = models.TextField()
 | 
			
		||||
    token = models.TextField()
 | 
			
		||||
    # Interface / API version of the service.
 | 
			
		||||
    interface = models.PositiveSmallIntegerField(default=1)
 | 
			
		||||
 | 
			
		||||
    # Valid interfaces are {generic, zulip_bot_service, slack}
 | 
			
		||||
    GENERIC = 1
 | 
			
		||||
    SLACK = 2
 | 
			
		||||
 | 
			
		||||
    ALLOWED_INTERFACE_TYPES = [
 | 
			
		||||
        GENERIC,
 | 
			
		||||
        SLACK,
 | 
			
		||||
    ]
 | 
			
		||||
    # N.B. If we used Django's choice=... we would get this for free (kinda)
 | 
			
		||||
    _interfaces: Dict[int, str] = {
 | 
			
		||||
        GENERIC: GENERIC_INTERFACE,
 | 
			
		||||
        SLACK: SLACK_INTERFACE,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def interface_name(self) -> str:
 | 
			
		||||
        # Raises KeyError if invalid
 | 
			
		||||
        return self._interfaces[self.interface]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_bot_services(user_profile_id: int) -> List[Service]:
 | 
			
		||||
    return list(Service.objects.filter(user_profile_id=user_profile_id))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_service_profile(user_profile_id: int, service_name: str) -> Service:
 | 
			
		||||
    return Service.objects.get(user_profile_id=user_profile_id, name=service_name)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BotStorageData(models.Model):
 | 
			
		||||
    bot_profile = models.ForeignKey(UserProfile, on_delete=CASCADE)
 | 
			
		||||
    key = models.TextField(db_index=True)
 | 
			
		||||
    value = models.TextField()
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        unique_together = ("bot_profile", "key")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BotConfigData(models.Model):
 | 
			
		||||
    bot_profile = models.ForeignKey(UserProfile, on_delete=CASCADE)
 | 
			
		||||
    key = models.TextField(db_index=True)
 | 
			
		||||
    value = models.TextField()
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        unique_together = ("bot_profile", "key")
 | 
			
		||||
@@ -17,14 +17,8 @@ from zerver.lib.bot_lib import get_bot_handler
 | 
			
		||||
from zerver.lib.integrations import EMBEDDED_BOTS, WebhookIntegration
 | 
			
		||||
from zerver.lib.test_classes import UploadSerializeMixin, ZulipTestCase
 | 
			
		||||
from zerver.lib.test_helpers import avatar_disk_path, get_test_image_file
 | 
			
		||||
from zerver.models import (
 | 
			
		||||
    Realm,
 | 
			
		||||
    RealmUserDefault,
 | 
			
		||||
    Service,
 | 
			
		||||
    Subscription,
 | 
			
		||||
    UserProfile,
 | 
			
		||||
    get_bot_services,
 | 
			
		||||
)
 | 
			
		||||
from zerver.models import Realm, RealmUserDefault, Service, Subscription, UserProfile
 | 
			
		||||
from zerver.models.bots import get_bot_services
 | 
			
		||||
from zerver.models.realms import get_realm
 | 
			
		||||
from zerver.models.streams import get_stream
 | 
			
		||||
from zerver.models.users import get_user, is_cross_realm_bot_email
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,8 @@ from typing_extensions import override
 | 
			
		||||
from zerver.lib.bot_lib import EmbeddedBotQuitError
 | 
			
		||||
from zerver.lib.display_recipient import get_display_recipient
 | 
			
		||||
from zerver.lib.test_classes import ZulipTestCase
 | 
			
		||||
from zerver.models import UserProfile, get_service_profile
 | 
			
		||||
from zerver.models import UserProfile
 | 
			
		||||
from zerver.models.bots import get_service_profile
 | 
			
		||||
from zerver.models.realms import get_realm
 | 
			
		||||
from zerver.models.users import get_user
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,8 @@ from zerver.lib.outgoing_webhook import get_service_interface_class, process_suc
 | 
			
		||||
from zerver.lib.test_classes import ZulipTestCase
 | 
			
		||||
from zerver.lib.timestamp import datetime_to_timestamp
 | 
			
		||||
from zerver.lib.topic import TOPIC_NAME
 | 
			
		||||
from zerver.models import SLACK_INTERFACE, Message
 | 
			
		||||
from zerver.models import Message
 | 
			
		||||
from zerver.models.bots import SLACK_INTERFACE
 | 
			
		||||
from zerver.models.realms import get_realm
 | 
			
		||||
from zerver.models.scheduled_jobs import NotificationTriggers
 | 
			
		||||
from zerver.models.streams import get_stream
 | 
			
		||||
 
 | 
			
		||||
@@ -104,8 +104,8 @@ from zerver.models import (
 | 
			
		||||
    Stream,
 | 
			
		||||
    UserMessage,
 | 
			
		||||
    UserProfile,
 | 
			
		||||
    get_bot_services,
 | 
			
		||||
)
 | 
			
		||||
from zerver.models.bots import get_bot_services
 | 
			
		||||
from zerver.models.clients import get_client
 | 
			
		||||
from zerver.models.prereg_users import filter_to_valid_prereg_users
 | 
			
		||||
from zerver.models.users import get_system_bot, get_user_profile_by_id
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user