def __name_set(self, val): """ :type self: ObjectDB """ # convert color codes val = sub_old_ansi(val) self.db.colored_name = val self.key = parse_ansi(val, strip_ansi=True) self.save()
def do_story_switches(self): if not self.args and not self.switches: self.switches.append("proof") if not self.switches or "body" in self.switches: self.draft.body = self.args if "title" in self.switches: title = sub_old_ansi(self.args) raw_title = parse_ansi(title, strip_ansi=True) if WrittenWork.objects.filter(title__iexact=raw_title).exists(): raise self.error_class( "Sorry, a written work already exists with that title. " "Try adding a number, (eg: 'Part II').") self.draft.colored_title = title self.draft.title = raw_title if "language" in self.switches: lhs = self.lhs.lower() if lhs and lhs not in self.caller.languages.known_languages: self.msg("You cannot speak that language.") return self.draft.language = lhs if "finish" in self.switches: title = self.draft.title colored_title = self.draft.colored_title body = self.draft.body lang = self.draft.language or "" if not title: raise self.error_class("Still needs a title set.") if not body: raise self.error_class("Still needs a body set.") story = self.caller.authored_works.create( title=title, body=body, language=lang, colored_title=colored_title) self.msg( f"You have created '{story}' (#{story.id}). Use |cwrite/add|n " f"to add it as a chapter to a book.") del self.caller.ndb.story_draft return # "proof" switch and others fall down to here, to display progress self.msg(self.display(), options={"box": True})
def msg(self, text=None, from_obj=None, session=None, options=None, **kwargs): """ :type self: ObjectDB :param text: str or tuple :param from_obj: ObjectDB :param session: Session :param options: dict :param kwargs: dict """ # if we have nothing to receive message, we're done. if not self.sessions.all(): return # compatibility change for Evennia changing text to be either str or tuple if hasattr(text, '__iter__'): text = text[0] options = options or {} options.update(kwargs.get('options', {})) try: text = str(text) except (TypeError, UnicodeDecodeError, ValueError): pass if text.endswith("|"): text += "{n" text = sub_old_ansi(text) if from_obj and isinstance(from_obj, dict): # somehow our from_obj had a dict passed to it. Fix it up. # noinspection PyBroadException try: options.update(from_obj) from_obj = None except Exception: import traceback traceback.print_exc() lang = options.get('language', None) msg_content = options.get('msg_content', None) if lang and msg_content: try: if not self.check_permstring("builders") and lang.lower( ) not in self.languages.known_languages: text = text.replace( msg_content, "<Something in a language that you don't understand>.") except AttributeError: pass if options.get('is_pose', False): if self.db.posebreak: text = "\n" + text name_color = self.db.name_color if name_color: text = text.replace(self.key, name_color + self.key + "{n") quote_color = self.db.pose_quote_color # colorize people's quotes with the given text if quote_color: text = RE_COLOR.sub(r'%s"\1"{n' % quote_color, text) if name_color: # counts the instances of name replacement inside quotes and recolorizes for _ in range(0, text.count("%s{n" % self.key)): text = self.namex.sub( r'"\1%s%s\2"' % (self.key, quote_color), text) if self.ndb.pose_history is None: self.ndb.pose_history = [] if from_obj == self: self.ndb.pose_history = [] else: try: origin = from_obj if not from_obj and options.get('is_magic', False): origin = "Magic System" self.ndb.pose_history.append((str(origin), text)) except AttributeError: pass if options.get('box', False): text = text_box(text) if options.get('roll', False): if self.attributes.has("dice_string"): text = "{w<" + self.db.dice_string + "> {n" + text if options.get('is_magic', False): if text[0] == "\n": text = text[1:] text = "{w<" + self.magic_word + "> |n" + text if options.get('is_pose'): if self.db.posebreak: text = "\n" + text try: if self.char_ob: msg_sep = self.tags.get("newline_on_messages") player_ob = self else: msg_sep = self.player_ob.tags.get("newline_on_messages") player_ob = self.player_ob except AttributeError: msg_sep = None player_ob = self try: if msg_sep: text += "\n" except (TypeError, ValueError): pass try: if from_obj and (options.get('is_pose', False) or options.get('log_msg', False)): private_msg = False if hasattr(self, 'location') and hasattr( from_obj, 'location') and self.location == from_obj.location: if self.location.tags.get("private"): private_msg = True if not private_msg: player_ob.log_message(from_obj, text) except AttributeError: pass text = self.strip_ascii_from_tags(text) super(MsgMixins, self).msg(text, from_obj, session, options, **kwargs)
def convert_descs_to_written_works(apps, schema_editor): """ This iterates over all the Readable typeclassed objects we have, and tries to convert their descriptions into WrittenWorks. In cases where their descs are built up of templates or translated texts, those are converted to WrittenWorks first, and then the BookChapters are created to associate the works with the book. For descs, a WrittenWork is created, which we'll compare future descs against to see if there's duplicates. """ ObjectDB = apps.get_model("objects", "ObjectDB") WrittenWork = apps.get_model("templates", "WrittenWork") BookChapter = apps.get_model("templates", "BookChapter") ChapterSignature = apps.get_model("templates", "ChapterSignature") readable = ObjectDB.objects.filter( db_typeclass_path="typeclasses.readable.readable.Readable" ) # different mappings desc_to_work = {} template_to_work = {} authors = {} def get_author(book_object): try: author_tuple = book_object.db_attributes.get(db_key="author").db_value return get_dbobj_from_tuple(author_tuple) except (ObjectDoesNotExist, TypeError, IndexError): return None def get_dbobj_from_tuple(obj_tuple): try: obj_pk = obj_tuple[-1] if obj_pk in authors: return authors[obj_pk] else: author_obj = ObjectDB.objects.get(id=obj_pk) authors[obj_pk] = author_obj return author_obj except (ObjectDoesNotExist, TypeError, IndexError): return None def get_desc(book_object): try: desc_attr = book_object.db_attributes.get(db_key="desc") except ObjectDoesNotExist: # if they have no desc, it's an empty book. skip it return # if its desc was that it's a blank book, delete the attribute and skip it if desc_attr.db_value == OLD_BASE_DESC: desc_attr.delete() return return desc_attr def get_signers(book_object): try: signed_attr = book_object.db_attributes.get(db_key="signed") signers_objects = [] for tup in signed_attr.db_value: obj = get_dbobj_from_tuple(tup) if obj: signers_objects.append(obj) signed_attr.delete() return signers_objects except (ObjectDoesNotExist, ValueError, TypeError): return [] def add_work_and_chapter_for_desc(book_object, desc_attr, chapter_num, author_obj): # check if work already exists body = desc_attr.db_value if body in desc_to_work: work_obj = desc_to_work[body] else: work_title = book_object.db_key num_matches = WrittenWork.objects.filter( title__startswith=book_object.db_key ).count() if num_matches: work_title += f" {num_matches + 1}" # create the work_obj for the body work_obj = WrittenWork.objects.create( body=desc_attr.db_value, title=work_title, author=author_obj ) desc_to_work[body] = work_obj # create chapter return BookChapter.objects.get_or_create( defaults=dict(number=chapter_num), written_work=work_obj, objectdb=book_object, )[0] def get_max_chapter_num(book_object): agg = book_object.book_chapters.aggregate(max_chapter=models.Max("number")) return agg.get("max_chapter", 0) or 0 readable.update(db_cmdset_storage=None) for book in readable: chapter_number = 1 desc = get_desc(book) if not desc: continue templates = book.template_set.all() if templates: # if we have templates, the desc is assumed it just be a list of templates # we'll convert templates to WrittenWorks and add chapters for them print(f"Processing templates for {book.db_key} (ID #{book.id})") for template in templates: if template.id in template_to_work: new_work = template_to_work[template.id] elif template.desc in desc_to_work: new_work = desc_to_work[template.desc] else: colored_title = sub_old_ansi(template.title) title = parse_ansi(colored_title, strip_ansi=True) if colored_title == title: colored_title = "" # try to get author author = get_author(book) # check for unique title title_matches = WrittenWork.objects.filter( title__startswith=title ).count() if title_matches: title += f" {title_matches + 1}" colored_title += f" {title_matches + 1}" new_work = WrittenWork.objects.create( body=template.desc, title=title, colored_title=colored_title, owner=template.owner, author=author, ) template_to_work[template.id] = new_work desc_to_work[template.desc] = new_work # add work to chapters for the book BookChapter.objects.get_or_create( defaults=dict(number=chapter_number), written_work=new_work, objectdb=book, ) chapter_number += 1 # get rid of old desc and move on desc.delete() continue # convert books with translated descs translations = book.translations.all() if translations: print(f"Processing translations for {book.db_key} (ID #{book.id})") base_title = book.db_key chapter_number = get_max_chapter_num(book) + 1 # desc should be first chapter author = get_author(book) add_work_and_chapter_for_desc(book, desc, chapter_number, author) for translation in translations: chapter_number += 1 if translation.description in desc_to_work: work = desc_to_work[translation.description] else: # convert translations into WrittenWorks of appropriate language title = base_title if chapter_number > 1: title += f" Chapter {chapter_number}" work = WrittenWork.objects.create( language=translation.language, body=translation.description, title=title, author=author, ) desc_to_work[translation.description] = work # add bookchapter for each converted translation BookChapter.objects.get_or_create( defaults=dict(number=chapter_number), written_work=work, objectdb=book, ) # get rid of old translation translation.delete() desc.delete() continue print(f"Processing book {book.db_key} (ID #{book.id})") author = get_author(book) chapter = add_work_and_chapter_for_desc(book, desc, 1, author) desc.delete() signers = get_signers(book) for signer in signers: ChapterSignature.objects.create(book_chapter=chapter, signer=signer)