@classmethod<EOL><INDENT>def create_collection(cls, href, collection=None, props=None):<DEDENT>
<EOL>attributes = _get_attributes_from_path(href)<EOL>if len(attributes) <= <NUM_LIT:1>:<EOL><INDENT>raise PrincipalNotAllowedError<EOL><DEDENT>if not props:<EOL><INDENT>props = {}<EOL><DEDENT>if not props.get("<STR_LIT>") and collection:<EOL><INDENT>props["<STR_LIT>"] = collection[<NUM_LIT:0>].name<EOL><DEDENT>try:<EOL><INDENT>self = cls(href, principal=False, tag=props.get("<STR_LIT>"))<EOL><DEDENT>except api.exceptions.DoesNotExist:<EOL><INDENT>user_path = posixpath.join('<STR_LIT:/>', cls.user)<EOL>collection_name = hashlib.sha256(str(time.time()).encode()).hexdigest()<EOL>sane_path = posixpath.join(user_path, collection_name)<EOL>if props.get("<STR_LIT>") == "<STR_LIT>":<EOL><INDENT>inst = api.Calendar.create(cls.etesync, collection_name, None)<EOL><DEDENT>elif props.get("<STR_LIT>") == "<STR_LIT>":<EOL><INDENT>inst = api.AddressBook.create(cls.etesync, collection_name, None)<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>inst.save()<EOL>self = cls(sane_path, principal=False)<EOL><DEDENT>self.set_meta(props)<EOL>if collection:<EOL><INDENT>if props.get("<STR_LIT>") == "<STR_LIT>":<EOL><INDENT>collection, = collection<EOL>items = []<EOL>for content in ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>items.extend(<EOL>getattr(collection, "<STR_LIT>" % content, []))<EOL><DEDENT>items_by_uid = groupby(sorted(items, key=get_uid), get_uid)<EOL>vobject_items = {}<EOL>for uid, items in items_by_uid:<EOL><INDENT>new_collection = vobject.iCalendar()<EOL>for item in items:<EOL><INDENT>new_collection.add(item)<EOL><DEDENT>href = self._find_available_file_name(<EOL>vobject_items.get)<EOL>vobject_items[href] = new_collection<EOL><DEDENT>self.upload_all_nonatomic(vobject_items)<EOL><DEDENT>elif props.get("<STR_LIT>") == "<STR_LIT>":<EOL><INDENT>vobject_items = {}<EOL>for card in collection:<EOL><INDENT>href = self._find_available_file_name(<EOL>vobject_items.get)<EOL>vobject_items[href] = card<EOL><DEDENT>self.upload_all_nonatomic(vobject_items)<EOL><DEDENT><DEDENT>return self<EOL>
Create a collection.

        If the collection already exists and neither ``collection`` nor
        ``props`` are set, this method shouldn't do anything. Otherwise the
        existing collection must be replaced.

        ``collection`` is a list of vobject components.

        ``props`` are metadata values for the collection.

        ``props["tag"]`` is the type of collection (VCALENDAR or
        VADDRESSBOOK). If the key ``tag`` is missing, it is guessed from the
        collection.