Beispiel #1
0
 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()
Beispiel #2
0
 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})
Beispiel #3
0
 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)