def generate_id(cls, ticket_name: str) -> str: """Generates key for the instance of AppFeedbackReportTicketModel class in the required format with the arguments provided. Args: ticket_name: str. The name assigned to the ticket on creation. Returns: str. The generated ID for this entity using the current datetime in milliseconds (as the entity's creation timestamp), a SHA1 hash of the ticket_name, and a random string, of the form '[creation_datetime_msec]:[hash(ticket_name)]:[random hash]'. """ current_datetime_in_msec = utils.get_time_in_millisecs( datetime.datetime.utcnow()) for _ in python_utils.RANGE(base_models.MAX_RETRIES): name_hash = utils.convert_to_hash(ticket_name, base_models.ID_LENGTH) random_hash = utils.convert_to_hash( python_utils.UNICODE( utils.get_random_int(base_models.RAND_RANGE)), base_models.ID_LENGTH) new_id = '%s.%s.%s' % (int(current_datetime_in_msec), name_hash, random_hash) if not cls.get_by_id(new_id): return new_id raise Exception( 'The id generator for AppFeedbackReportTicketModel is producing too' 'many collisions.')
def test_convert_to_hash(self) -> None: """Test convert_to_hash() method.""" orig_string = 'name_to_convert' full_hash = utils.convert_to_hash(orig_string, 28) abbreviated_hash = utils.convert_to_hash(orig_string, 5) self.assertEqual(len(full_hash), 28) self.assertEqual(len(abbreviated_hash), 5) self.assertEqual(full_hash[:5], abbreviated_hash) self.assertTrue(full_hash.isalnum())
def _generate_id(cls, exp_id: str) -> str: """Generates a unique id for the training job of the form '[exp_id].[random hash of 16 chars]'. Args: exp_id: str. ID of the exploration. Returns: str. ID of the new ClassifierTrainingJobModel instance. Raises: Exception. The id generator for ClassifierTrainingJobModel is producing too many collisions. """ for _ in python_utils.RANGE(base_models.MAX_RETRIES): new_id = '%s.%s' % ( exp_id, utils.convert_to_hash( python_utils.UNICODE( utils.get_random_int(base_models.RAND_RANGE)), base_models.ID_LENGTH)) if not cls.get_by_id(new_id): return new_id raise Exception( 'The id generator for ClassifierTrainingJobModel is producing ' 'too many collisions.')
def generate_id(cls, platform: str, submitted_on_datetime: datetime.datetime) -> str: """Generates key for the instance of AppFeedbackReportModel class in the required format with the arguments provided. Args: platform: str. The platform the user is the report from. submitted_on_datetime: datetime.datetime. The datetime that the report was submitted on in UTC. Returns: str. The generated ID for this entity using platform, submitted_on_sec, and a random string, of the form '[platform].[submitted_on_msec].[random hash]'. """ submitted_datetime_in_msec = utils.get_time_in_millisecs( submitted_on_datetime) for _ in python_utils.RANGE(base_models.MAX_RETRIES): random_hash = utils.convert_to_hash( python_utils.UNICODE( utils.get_random_int(base_models.RAND_RANGE)), base_models.ID_LENGTH) new_id = '%s.%s.%s' % (platform, int(submitted_datetime_in_msec), random_hash) if not cls.get_by_id(new_id): return new_id raise Exception( 'The id generator for AppFeedbackReportModel is producing too ' 'many collisions.')
def _generate_id(cls, intent: str) -> str: """Generates an ID for a new SentEmailModel instance. Args: intent: str. The intent string, i.e. the purpose of the email. Valid intent strings are defined in feconf.py. Returns: str. The newly-generated ID for the SentEmailModel instance. Raises: Exception. The id generator for SentEmailModel is producing too many collisions. """ id_prefix = '%s.' % intent for _ in range(base_models.MAX_RETRIES): new_id = '%s.%s' % (id_prefix, utils.convert_to_hash( python_utils.UNICODE( utils.get_random_int( base_models.RAND_RANGE)), base_models.ID_LENGTH)) if not cls.get_by_id(new_id): return new_id raise Exception( 'The id generator for SentEmailModel is producing too many ' 'collisions.')
def get_machine_translation( cls, source_language_code: str, target_language_code: str, source_text: str ) -> Optional[MachineTranslationModel]: """Gets MachineTranslationModel by language codes and source text. Args: source_language_code: str. The language code for the source text language. Must be different from target_language_code. target_language_code: str. The language code for the target translation language. Must be different from source_language_code. source_text: str. The untranslated source text. Returns: MachineTranslationModel|None. The MachineTranslationModel instance corresponding to the given inputs, if such a translation exists, or None if no translation is found. """ hashed_source_text = utils.convert_to_hash(source_text, 50) instance_id = cls._generate_id( source_language_code, target_language_code, hashed_source_text) return cls.get(instance_id, strict=False)
def create(cls, source_language_code: str, target_language_code: str, source_text: str, translated_text: str) -> Optional[str]: """Creates a new MachineTranslationModel instance and returns its ID. Args: source_language_code: str. The language code for the source text language. Must be different from target_language_code. target_language_code: str. The language code for the target translation language. Must be different from source_language_code. source_text: str. The untranslated source text. translated_text: str. The machine generated translation of the source text into the target language. Returns: str|None. The id of the newly created MachineTranslationModel instance, or None if the inputs are invalid. """ if source_language_code is target_language_code: return None # SHA-1 always produces a 40 digit hash. 50 is chosen here to prevent # convert_to_hash from truncating the hash. hashed_source_text = utils.convert_to_hash(source_text, 50) entity_id = cls._generate_id(source_language_code, target_language_code, hashed_source_text) translation_entity = cls(id=entity_id, hashed_source_text=hashed_source_text, source_language_code=source_language_code, target_language_code=target_language_code, source_text=source_text, translated_text=translated_text) translation_entity.put() return entity_id
def _get_new_model_id(model_class: base_models.BaseModel) -> str: """Generates an ID for a new model. Returns: str. The new ID. """ for _ in range(_MAX_ID_GENERATION_ATTEMPTS): new_id = utils.convert_to_hash(uuid.uuid4().hex, 22) if model_class.get(new_id, strict=False) is None: return new_id raise RuntimeError('Failed to generate a unique ID after %d attempts' % (_MAX_ID_GENERATION_ATTEMPTS))
def _generate_hash(cls, recipient_id: str, email_subject: str, email_body: str) -> str: """Generate hash for a given recipient_id, email_subject and cleaned email_body. Args: recipient_id: str. The user ID of the email recipient. email_subject: str. The subject line of the email. email_body: str. The HTML content of the email body. Returns: str. The generated hash value of the given email. """ hash_value = utils.convert_to_hash( recipient_id + email_subject + email_body, 100) return hash_value
def generate_new_blog_post_id(cls) -> str: """Generates a new blog post ID which is unique and is in the form of random hash of 12 chars. Returns: str. A blog post ID that is different from the IDs of all the existing blog posts. Raises: Exception. There were too many collisions with existing blog post IDs when attempting to generate a new blog post ID. """ for _ in range(base_models.MAX_RETRIES): blog_post_id = utils.convert_to_hash( str(utils.get_random_int(base_models.RAND_RANGE)), base_models.ID_LENGTH) if not cls.get_by_id(blog_post_id): return blog_post_id raise Exception( 'New blog post id generator is producing too many collisions.')
def _get_new_id(cls) -> str: """Generates a unique ID for the question in the form of random hash of 12 chars. Returns: new_id: str. ID of the new QuestionModel instance. Raises: Exception. The ID generator for QuestionModel is producing too many collisions. """ for _ in range(base_models.MAX_RETRIES): new_id = utils.convert_to_hash( str(utils.get_random_int(base_models.RAND_RANGE)), base_models.ID_LENGTH) if not cls.get_by_id(new_id): return new_id raise Exception( 'The id generator for QuestionModel is producing too many ' 'collisions.')
def test_validate_convert_to_hash(self) -> None: with self.assertRaisesRegexp( # type: ignore[no-untyped-call] Exception, 'Expected string, received 1 of type %s' % type(1)): utils.convert_to_hash(1, 10) # type: ignore[arg-type]