Les tutoriels v2 (ZEP12) (tutorialv2/)

Module situé dans zds/tutorialv2/.

Modèles (models/)

Modèles de la base de donnée (database.py)

class zds.tutorialv2.models.database.ContentContribution(*args, **kwargs)

Content contributions

exception DoesNotExist
exception MultipleObjectsReturned
class zds.tutorialv2.models.database.ContentContributionRole(*args, **kwargs)

Contribution role of content

exception DoesNotExist
exception MultipleObjectsReturned
class zds.tutorialv2.models.database.ContentReaction(*args, **kwargs)

A comment written by any user about a PublishableContent they just read.

exception DoesNotExist
exception MultipleObjectsReturned
get_absolute_url()

Find the url to the reaction

Renvoie:

the url of the comment

Type renvoyé:

str

class zds.tutorialv2.models.database.ContentRead(*args, **kwargs)

Small model which keeps track of the user viewing tutorials.

It remembers the PublishableContent they read and what was the last Note at that time.

exception DoesNotExist
exception MultipleObjectsReturned
save(force_insert=False, force_update=False, using=None, update_fields=None)

Save this model but check that if we have not a related note it is because the user is content author.

class zds.tutorialv2.models.database.ContentSuggestion(id, publication, suggestion)
exception DoesNotExist
exception MultipleObjectsReturned
static get_random_public_suggestions(publication: PublishableContent, count: int)

Get random public suggestions for the given publication. At most count suggestions are returned.

class zds.tutorialv2.models.database.FakeChapter(chapter, main_container, parent_id)

A simple class that is used by ES to index chapters, constructed from the containers.

In mapping, this class defines PublishedContent as its parent. Also, indexing is done by the parent.

Note that this class is only indexable, not updatable, since it does not maintain value of es_already_indexed

get_es_document_as_bulk_action(index, action='index')

Overridden to handle parenting between chapter and PublishedContent

classmethod get_es_document_type()

value of the _type field in the index

classmethod get_es_mapping()

Define mapping and parenting

parent_model

alias de PublishedContent

class zds.tutorialv2.models.database.PickListOperation(id, content, operation, operation_date, version, staff_user, canceler_user, is_effective)
exception DoesNotExist
exception MultipleObjectsReturned
cancel(canceler, autosave=True)

Cancel a decision :param canceler: staff user :param autosave: if True saves the modification

save(**kwargs)

Save the current instance. Override this in a subclass if you want to control the saving process.

The “force_insert” and “force_update” parameters can be used to insist that the « save » must be an SQL insert or update (or equivalent for non-SQL backends), respectively. Normally, they should not be set.

class zds.tutorialv2.models.database.PublicationEvent(id, published_object, state_of_processing, format_requested, date)
exception DoesNotExist
exception MultipleObjectsReturned
class zds.tutorialv2.models.database.PublishableContent(*args, **kwargs)

A publishable content.

A PublishableContent retains metadata about a content in database, such as

  • authors, description, source (if the content comes from another website), subcategory, tags and licence ;

  • Thumbnail and gallery ;

  • Creation, publication and update date ;

  • Public, beta, validation and draft sha, for versioning ;

  • Comment support ;

  • Type, which is either 'ARTICLE', 'TUTORIAL' or 'OPINION'

exception DoesNotExist
exception MultipleObjectsReturned
add_tags(tag_collection)

Add all tags contained in tag_collection to this content. If a tag is unknown, it is added to the system. :param tag_collection: A collection of tags. :type tag_collection: list

antispam(user=None)

Check if the user is allowed to post in an tutorial according to the SPAM_LIMIT_SECONDS value.

Paramètres:

user – the user to check antispam. If None, current user is used.

Renvoie:

True if the user is not able to note (the elapsed time is not enough), False otherwise.

Type renvoyé:

bool

ensure all authors subscribe to gallery

first_note()
Renvoie:

the first post of a topic, written by topic’s author, if any.

Type renvoyé:

ContentReaction

property first_publication_date

traverse PublishedContent instances to find the first ever published and get its date :return: the first publication date :rtype: datetime

first_unread_note(user=None)
Renvoie:

Return the first note the user has unread.

Type renvoyé:

ContentReaction

get_absolute_contact_url(title='Collaboration')

Get url to send a new PM for collaboration

Paramètres:

title (str) – what is going to be in the title of the PM before the name of the content

Renvoie:

url to the PM creation form

Type renvoyé:

str

get_absolute_url_beta()

NOTE: it’s better to use the version contained in VersionedContent, if possible !

Renvoie:

absolute URL to the beta version the content

Type renvoyé:

str

get_absolute_url_online()

NOTE: it’s better to use the version contained in VersionedContent, if possible !

Renvoie:

absolute URL to the public version the content, if self.public_version is defined

Type renvoyé:

str

get_last_note()
Renvoie:

the last answer in the thread, if any.

Type renvoyé:

ContentReaction|None

get_note_count()

Count all the reactions to this content. Warning, if you did not pre process this number, a query will be sent

Renvoie:

number of notes in the content.

Type renvoyé:

int

get_repo_path(relative=False)

Get the path to the tutorial repository

Paramètres:

relative – if True, the path will be relative, absolute otherwise.

Renvoie:

physical path

Type renvoyé:

str

in_beta() bool

Return True if a beta version of the content exists, and False otherwise.

in_drafting() bool

Return True if a draft version of the content exists, and False otherwise.

in_public() bool

Return True if a public version of the content exists, and False otherwise.

in_validation() bool

Return True if a version of the content is in validation, and False otherwise.

insert_data_in_versioned(versioned)

Insert some additional data from database in a VersionedContent

Paramètres:

versioned – the VersionedContent to fill

is_beta(sha: str) bool

Return True if the given sha corresponds to the beta version, and False otherwise.

is_permanently_unpublished()

Is this content permanently unpublished by a moderator ?

is_public(sha: str) bool

Return True if the given sha corresponds to the public version, and False otherwise.

is_validation(sha: str) bool

Return True if the given sha corresponds to the version in validation, and False otherwise.

last_read_note()
Renvoie:

the last post the user has read.

Type renvoyé:

ContentReaction

load_manifest(sha=None, public=None)

Using git, load a specific version of the manifest. if sha is None, the draft/public version is used (if public is True).

Paramètres:
  • sha – version

  • public (PublishedContent) – if set with the right object, return the public version

Lève:
  • BadObject – if sha is not None and related version could not be found

  • OSError – if the path to the repository is wrong

  • NotAPublicVersion – if the sha does not correspond to a public version

Renvoie:

the manifest

Type renvoyé:

dict

load_version(sha=None, public=None)

Using git, load a specific version of the content. if sha is None, the draft/public version is used (if public is True).

Attention

for practical reason, the returned object is filled with information from DB.

Paramètres:
  • sha – version

  • public (PublishedContent) – if set with the right object, return the public version

Lève:
  • BadObject – if sha is not None and related version could not be found

  • OSError – if the path to the repository is wrong

  • NotAPublicVersion – if the sha does not correspond to a public version

Renvoie:

the versioned content

Type renvoyé:

zds.tutorialv2.models.versioned.VersionedContent

load_version_or_404(sha=None, public=None)

Using git, load a specific version of the content. if sha is None, the draft/public version is used (if public is True).

Paramètres:
  • sha – version

  • public (PublishedContent) – if set with the right object, return the public version

Lève:

Http404 – if sha is not None and related version could not be found

Renvoie:

the versioned content

Type renvoyé:

zds.tutorialv2.models.versioned.VersionedContent

repo_delete()

Delete the entities and their filesystem counterparts

requires_validation()

Check if content required a validation before publication. Used to check if JsFiddle is available too.

Renvoie:

Whether validation is required before publication.

Type renvoyé:

bool

save(*args, force_slug_update=False, update_date=True, **kwargs)

Rewrite the save() function to handle slug uniqueness

Paramètres:
  • update_date – if True will assign « update_date » property to now

  • force_slug_update – if True will try to update the slug

update(**fields)

wrapper arround self.objects.update

Paramètres:

fields – Fields to update

Renvoie:

modified self

class zds.tutorialv2.models.database.PublishedContent(*args, **kwargs)

A class that contains information on the published version of a content.

Used for quick url resolution, quick listing, and to know where the public version of the files are.

Linked to a PublishableContent for the rest. Don’t forget to add a .prefetch_related('content') !!

exception DoesNotExist
exception MultipleObjectsReturned
get_absolute_url()

For admin interface. get_absolute_url_online() should probably be directly used in other cases.

get_absolute_url_epub()

wrapper around self.get_absolute_url_to_extra_content('epub')

Renvoie:

URL to the epub version of the published content

Type renvoyé:

str

get_absolute_url_html()

wrapper around self.get_absolute_url_to_extra_content('html')

Renvoie:

URL to the HTML version of the published content

Type renvoyé:

str

get_absolute_url_md()

wrapper around self.get_absolute_url_to_extra_content('md')

Renvoie:

URL to the full markdown version of the published content

Type renvoyé:

str

get_absolute_url_pdf()

wrapper around self.get_absolute_url_to_extra_content('pdf')

Renvoie:

URL to the PDF version of the published content

Type renvoyé:

str

get_absolute_url_tex()

wrapper around self.get_absolute_url_to_extra_content('tex')

Renvoie:

URL to the tex version of the published content

Type renvoyé:

str

get_absolute_url_to_extra_content(type_)

Get the url that point to the extra content the user may want to download

Paramètres:

type (str) – the type inside allowed_type

Renvoie:

URL to a given extra content (note that no check for existence is done)

Type renvoyé:

str

get_absolute_url_zip()

wrapper around self.get_absolute_url_to_extra_content('zip')

Renvoie:

URL to the zip archive of the published content

Type renvoyé:

str

get_char_count(md_file_path=None)

Compute the number of letters for a given content

Paramètres:

md_file_path (str) – use another file to compute the number of letter rather than the default one.

Renvoie:

Number of letters in the md file

Type renvoyé:

int

classmethod get_es_django_indexable(force_reindexing=False)

Overridden to remove must_redirect=True (and prefetch stuffs).

get_es_document_source(excluded_fields=None)

Overridden to handle the fact that most information are versioned

classmethod get_es_indexable(force_reindexing=False)

Overridden to also include chapters

classmethod get_es_mapping()

Overridden to add pk into mapping.

Renvoie:

mapping object

Type renvoyé:

elasticsearch_dsl.Mapping

get_extra_contents_directory()
Renvoie:

path to all the “extra contents”

Type renvoyé:

str

get_size_epub()

Get the size of epub

Renvoie:

size of file

Type renvoyé:

int

get_size_file_type(type_)

Get the size of a given extra content. Is the size is not in database we get it and store it for next time.

Renvoie:

size of file

Type renvoyé:

int

get_size_html()

Get the size of html

Renvoie:

size of file

Type renvoyé:

int

get_size_md()

Get the size of md

Renvoie:

size of file

Type renvoyé:

int

get_size_pdf()

Get the size of pdf

Renvoie:

size of file

Type renvoyé:

int

get_size_tex()

Get the size of LaTeX file

Renvoie:

size of file

Type renvoyé:

int

get_size_zip()

Get the size of zip

Renvoie:

size of file

Type renvoyé:

int

has_epub()

Check if the standard epub version of the content is available

Renvoie:

True if available, False otherwise

Type renvoyé:

bool

has_md()

Check if the flat markdown version of the content is available

Renvoie:

True if available, False otherwise

Type renvoyé:

bool

has_pdf()

Check if the pdf version of the content is available

Renvoie:

True if available, False otherwise

Type renvoyé:

bool

has_tex()

Check if the latex version of the content is available

Renvoie:

True if available, False otherwise

Type renvoyé:

bool

has_type(type_)

check if a given extra content exists

Renvoie:

True if the file exists, False otherwhise

Type renvoyé:

bool

has_zip()

Check if the standard zip version of the content is available

Renvoie:

True if available, False otherwise

Type renvoyé:

bool

is_exported()

If the content has at least one export, it returns True

load_public_version()
Type renvoyé:

zds.tutorialv2.models.database.PublicContent

Renvoie:

the public content

load_public_version_or_404()
Renvoie:

the public content

Type renvoyé:

zds.tutorialv2.models.database.PublicContent

Lève:

Http404 – if the version is not available

meta_description()

Generate a description for the HTML tag <meta name=”description”>

class zds.tutorialv2.models.database.Validation(*args, **kwargs)

Content validation.

exception DoesNotExist
exception MultipleObjectsReturned
is_accept()

Check if the content is accepted

Renvoie:

True if status is accepted, False otherwise

Type renvoyé:

bool

is_cancel()

Check if the content is canceled

Renvoie:

True if status is canceled, False otherwise

Type renvoyé:

bool

is_pending()

Check if the validation is pending

Renvoie:

True if status is pending, False otherwise

Type renvoyé:

bool

is_pending_valid()

Check if the validation is pending (but there is a validator)

Renvoie:

True if status is pending/valid, False otherwise

Type renvoyé:

bool

is_reject()

Check if the content is rejected

Renvoie:

True if status is rejected, False otherwise

Type renvoyé:

bool

catch the post_delete signal to ensure the deletion of the gallery (otherwise, you generate a loop)

zds.tutorialv2.models.database.delete_published_content_in_elasticsearch(sender, instance, **kwargs)

Catch the pre_delete signal to ensure the deletion in ES. Also, handle the deletion of the corresponding chapters.

zds.tutorialv2.models.database.delete_published_content_in_elasticsearch_if_set_to_redirect(sender, instance, **kwargs)

If the slug of the content changes, the must_redirect field is set to True and a new PublishedContnent is created. To avoid duplicates, the previous ones must be removed from ES.

zds.tutorialv2.models.database.delete_repo(sender, instance, **kwargs)

catch the pre_delete signal to ensure the deletion of the repository if a PublishableContent is deleted

zds.tutorialv2.models.database.transfer_paternity_receiver(sender, instance, **kwargs)

transfer paternity to external user on user deletion

Modèles « versionnés » (versioned.py)

class zds.tutorialv2.models.versioned.Container(title, slug='', parent=None, position_in_parent=1)

A container, which can have sub-Containers or Extracts.

A Container has a title, a introduction and a conclusion, a parent (which can be None) and a position into this parent (which is 1 by default).

It also has a tree depth.

A container could be either a tutorial/article/opinion, a part or a chapter.

add_container(container, generate_slug=False)

Add a child Container, but only if no extract were previously added and tree depth is lower than 2.

Attention

This function will raise an Exception if the publication is an article

Paramètres:
  • container – the new container

  • generate_slug – if True, asks the top container a unique slug for this object

Lève:

InvalidOperationError – if the new container cannot be added. Please use can_add_container first to make sure you can use add_container.

add_extract(extract, generate_slug=False)

Add a child container, but only if no container were previously added

Paramètres:
  • extract – the new extract

  • generate_slug – if True, ask the top container a unique slug for this object

Lève:

InvalidOperationError – if the extract can’t be added to this container.

can_add_container()
Renvoie:

True if this container accepts child containers, False otherwise

Type renvoyé:

bool

can_add_extract()

Return True if this container can contain extracts, i.e doesn’t contain any container (only zero or more extracts) and is not too deeply nested.

Renvoie:

True if this container accept child extract, False otherwise

Type renvoyé:

bool

compute_hash()

Compute an MD5 hash from the introduction and conclusion, for comparison purpose

Renvoie:

MD5 hash

Type renvoyé:

str

get_absolute_url()
Renvoie:

url to access the container

Type renvoyé:

str

get_absolute_url_beta()
Renvoie:

url to access the container in beta

Type renvoyé:

str

get_absolute_url_online()
Renvoie:

the “online version” of the url

Type renvoyé:

str

get_conclusion()
Renvoie:

the conclusion from the file in self.conclusion

Type renvoyé:

str

get_conclusion_online()

The conclusion content for online version.

This method should be only used in templates

Renvoie:

the full text if introduction exists, empty string otherwise

Type renvoyé:

str

get_delete_url()
Renvoie:

url to edit the container

Type renvoyé:

str

get_edit_url()
Renvoie:

url to edit the container

Type renvoyé:

str

get_introduction()
Renvoie:

the introduction from the file in self.introduction

Type renvoyé:

str

get_introduction_online()

The introduction content for online version.

This method should be only used in templates

Renvoie:

the full text if introduction exists, empty string otherwise

Type renvoyé:

str

get_last_child_position()
Renvoie:

the position of the last child

Type:

int

get_level_as_string()

Get a word (Part/Chapter/Section) for the container level

Attention

this deals with internationalized string

Renvoie:

The string representation of this level

Type renvoyé:

str

get_list_of_containers()

Return a flat list of containers following the reading order. Extracts are not included. Example, if called on the top container: [VersionedContent, Part1, Chapter1, Chapter2, Chapter3, Part2, …]

get_next_level_as_string()

Same as self.get_level_as_string() but try to guess the level of this container’s children

Renvoie:

The string representation of next level (upper)

Type renvoyé:

str

get_path(relative=False, os_sensitive=True)

Get the physical path to the draft version of the container. Note: this function rely on the fact that the top container is VersionedContainer.

Paramètres:
  • relative (bool) – if True, the path will be relative, absolute otherwise.

  • os_sensitive – if True will use os.path.join to ensure compatibility with all OS, otherwise will build with /, mainly for urls.

Renvoie:

physical path

Type renvoyé:

str

get_prod_path(relative=False, file_ext='html')

Get the physical path to the public version of the container. If the container have extracts, then it returns the final HTML file.

Paramètres:
  • file_ext – the dumped file extension

  • relative (bool) – return a relative path instead of an absolute one

Renvoie:

Renvoie:

physical path

Type renvoyé:

str

get_tree_depth()

Return the depth where this container is found.

The tree depth of a container is the number of parents of that container. It is always lower that 3 because a nested container can have at most two parents.

Keep in mind that extracts can reach a depth of 3 in the document tree since there are leaves. Containers are not leaves.

Renvoie:

Tree depth

Type renvoyé:

int

get_tree_level()

Return the level in the tree of this container, i.e the depth of its deepest child.

Renvoie:

tree level

Type renvoyé:

int

get_unique_slug(title)

Generate a slug from the title and check if it is already in slug pool. If true, add a « -x » to the end, where « x » is a number starting from 1. When generated, it is added to the slug pool.

Note that the slug cannot be larger than settings.ZDS_APP['content']['max_slug_size'], due to maximum file size limitation.

Paramètres:

title – title from which the slug is generated (with slugify())

Renvoie:

the unique slug

Type renvoyé:

str

get_url_path(base_url='')

Return the path to the container for use in URLs. Preprend with base_url if specified.

has_child_with_path(child_path)

Return True if this container has a child matching the given full path.

Paramètres:

child_path – the full path (/maincontainer/subc1/subc2/childslug) we want to check

Renvoie:

True if the child is found, False otherwise

Type renvoyé:

bool

has_extracts()

Note: This function relies on the fact that every child has the same type.

Renvoie:

True if the container contains extracts, False otherwise.

Type renvoyé:

bool

has_sub_containers()

Note: this function relies on the fact that every child has the same type.

Renvoie:

True if the container contains other containers, False otherwise.

Type renvoyé:

bool

is_chapter()

Check if the container level is Chapter

Renvoie:

True if the container level is Chapter

Type renvoyé:

bool

is_validable()

Return True if the container would be in the public version if the content is validated.

long_slug()
Renvoie:

a long slug which embeds parent slugs

Type renvoyé:

str

move_child_after(child_slug, refer_slug)

Change the child’s ordering by moving the child to be below the reference child. This method does not automaticaly update the repo

Paramètres:
  • child_slug – the child’s slug

  • refer_slug – the referent child’s slug.

Lève:

ValueError – if one slug does not refer to an existing child

move_child_before(child_slug, refer_slug)

Change the child’s ordering by moving the child to be just above the reference child. This method does not automaticaly update the repo.

Paramètres:
  • child_slug – the child’s slug

  • refer_slug – the referent child’s slug.

Lève:

ValueError – if one slug does not refer to an existing child

move_child_down(child_slug)

Change the child’s ordering by moving down the child whose slug equals child_slug. This method does not automaticaly update the repo.

Paramètres:

child_slug – the child’s slug

Lève:
  • ValueError – if the slug does not refer to an existing child

  • IndexError – if the extract is already the last child

move_child_up(child_slug)

Change the child’s ordering by moving up the child whose slug equals child_slug. This method does not automaticaly update the repo.

Paramètres:

child_slug – the child’s slug

Lève:
  • ValueError – if the slug does not refer to an existing child

  • IndexError – if the extract is already the first child

next_level_is_chapter()

Same as self.is_chapter() but check the container’s children

Renvoie:

True if the container next level is Chapter

Type renvoyé:

bool

publish_extracts(base_dir, is_js, template, failure_exception)

Publish the current element thanks to a templated view.

Paramètres:
  • base_dir – directory into which we will put the result

  • is_js – jsfiddle activation flag

  • template – templated view name

  • failure_exception – the exception to throw when we fail

Renvoie:

repo_add_container(title, introduction, conclusion, commit_message='', do_commit=True, slug=None, ready_to_publish=None)
Paramètres:
  • title – title of the new container

  • introduction – text of its introduction

  • conclusion – text of its conclusion

  • commit_message – commit message that will be used instead of the default one

  • do_commit – perform the commit in repository if True

Renvoie:

commit sha

Type renvoyé:

str

repo_add_extract(title, text, commit_message='', do_commit=True, slug=None)
Paramètres:
  • title – title of the new extract

  • text – text of the new extract

  • commit_message – commit message that will be used instead of the default one

  • do_commit – perform the commit in repository if True

  • generate_slug – indicates that is must generate slug

Renvoie:

commit sha

Type renvoyé:

str

repo_delete(commit_message='', do_commit=True)
Paramètres:
  • commit_message – commit message used instead of default one if provided

  • do_commit – tells if we have to commit the change now or let the outer program do it

Renvoie:

commit sha

Type renvoyé:

str

repo_update(title, introduction, conclusion, commit_message='', do_commit=True, update_slug=True)

Update the container information and commit them into the repository

Paramètres:
  • title – the new title

  • introduction – the new introduction text

  • conclusion – the new conclusion text

  • commit_message – commit message that will be used instead of the default one

  • do_commit – perform the commit in repository if True

Renvoie:

commit sha

Type renvoyé:

str

traverse(only_container=True)

Traverse the container.

Paramètres:

only_container – if we only want container’s paths, not extract

Renvoie:

a generator that traverse all the container recursively (depth traversal)

Type renvoyé:

collections.Iterable[Container|Extract]

update_children()

Update the path for introduction and conclusion for the container and all its children. If the children is an extract, update the path to the text instead. This function is useful when self.slug has changed.

Note: this function does not account for a different arrangement of the files.

class zds.tutorialv2.models.versioned.Extract(title, slug='', container=None, position_in_parent=1)

A content extract from a Container.

It has a title, a position in the parent container and a text.

compute_hash()

Compute an MD5 hash from the text, for comparison purpose

Renvoie:

MD5 hash of the text

Type renvoyé:

str

get_absolute_url()

Find the url that point to the offline version of this extract

Renvoie:

the url to access the tutorial offline

Type renvoyé:

str

get_absolute_url_beta()
Renvoie:

the url to access the tutorial when in beta

Type renvoyé:

str

get_absolute_url_online()
Renvoie:

the url to access the tutorial when online

Type renvoyé:

str

get_delete_url()
Renvoie:

URL to delete the extract

Type renvoyé:

str

get_edit_url()
Renvoie:

url to edit the extract

Type renvoyé:

str

get_first_level_slug()
Renvoie:

the first_level_slug, if (and only if) the parent container is a chapter

Type renvoyé:

str

get_full_slug()

Get the slug of curent extract with its full path (part1/chapter1/slug_of_extract).

This method is an alias to extract.get_path(True)[:-3] (removes the .md file extension).

Type renvoyé:

str

get_path(relative=False)

Get the physical path to the draft version of the extract. :param relative: if True, the path will be relative, absolute otherwise. :return: physical path :rtype: str

get_text()
Renvoie:

versioned text

Type renvoyé:

str

get_tree_depth()

Return the depth where this extract is found.

The tree depth of an extract is the number of parents of that extract. It is always lower that 4 because an extract can have at most three parents.

Keep in mind that containers can’t reach a depth of 3 in the document tree since there are not leaves.

Renvoie:

Tree depth

Type renvoyé:

int

repo_delete(commit_message='', do_commit=True)
Paramètres:
  • commit_message – commit message used instead of default one if provided

  • do_commit – tells if we have to commit the change now or let the outer program do it

Renvoie:

commit sha, None if no commit is done

Type renvoyé:

str

repo_update(title, text, commit_message='', do_commit=True)
Paramètres:
  • title – new title of the extract

  • text – new text of the extract

  • commit_message – commit message that will be used instead of the default one

Renvoie:

commit sha

Type renvoyé:

str

exception zds.tutorialv2.models.versioned.NotAPublicVersion

Exception raised when a given version is not a public version as it should be

class zds.tutorialv2.models.versioned.PublicContent(current_version, _type, title, slug)

This is the public version of a VersionedContent, created from public repository

class zds.tutorialv2.models.versioned.VersionedContent(current_version, _type, title, slug, slug_repository='')

This class is used to handle a specific version of a content.

It is created from the “manifest.json” file, and could dump information in it.

For simplicity, it also contains read-only DB information filled at the creation.

change_child_directory(child, adoptive_parent)

Move an element of this content to a new location. This method changes the repository index and stage every change but does not commit.

Paramètres:
  • child – the child we want to move, can be either an Extract or a Container object

  • adoptive_parent – the container where the child will be moved, must be a Container object

commit_changes(commit_message)

Commit change made to the repository

Paramètres:

commit_message – The message that will appear in content history

Renvoie:

commit sha

Type renvoyé:

str

dump_json(path=None)

Write the JSON into file

Paramètres:

path – path to the file. If None, write in “manifest.json”

get_absolute_url(version=None)
Renvoie:

url to access the container

Type renvoyé:

str

get_absolute_url_beta()
Renvoie:

the url to access the tutorial when in beta

Type renvoyé:

str

get_absolute_url_online()
Renvoie:

the url to access the content when online

Type renvoyé:

str

get_json()
Renvoie:

raw JSON file

Type renvoyé:

str

get_list_of_chapters()
Renvoie:

a list of chapters (Container which contains Extracts) in the reading order

Type renvoyé:

list[Container]

get_path(relative=False, use_current_slug=False)

Get the physical path to the draft version of the Content.

Paramètres:
  • relative – if True, the path will be relative, absolute otherwise.

  • use_current_slug – if True, use self.slug instead of self.slug_last_draft

Renvoie:

physical path

Type renvoyé:

str

get_prod_path(relative=False, file_ext='html')

Get the physical path to the public version of the content. If it has one or more extracts (if it is a mini-tutorial or an article), return the path of the HTML file.

Paramètres:

relative – return the relative path instead of the absolute one

Renvoie:

physical path

Type renvoyé:

str

repo_update_top_container(title, slug, introduction, conclusion, commit_message='', do_commit=True)

Update the top container information and commit them into the repository. Note that this is slightly different from the repo_update() function, because slug is generated using DB

Paramètres:
  • title – the new title

  • slug – the new slug, according to title (choose using DB!!)

  • introduction – the new introduction text

  • conclusion – the new conclusion text

  • commit_message – commit message that will be used instead of the default one

  • do_commit – if True, also commit change

Renvoie:

commit sha

Type renvoyé:

str

textual_type()

Create a internationalized string with the human readable type of this content e.g “The Article”

Renvoie:

internationalized string

Type renvoyé:

str

Les managers (managers.py)

class zds.tutorialv2.managers.PublishableContentManager(*args, **kwargs)

get_last_articles(number=0)
..attention:

this one uses a raw subquery for historical reasons. It will hopefully be replaced one day by an ORM primitive.

Renvoie:

list of last articles expanded with “count_note” property that prefetches number of comments

Type renvoyé:

list

get_last_opinions()

This depends on settings.ZDS_APP[“opinions”][“home_number”] parameter.

Renvoie:

list of last opinions

Type renvoyé:

list

get_last_tutorials(number=0)

get list of last published tutorial

Paramètres:

number – number of tutorial you want. By default it is interpreted as settings.ZDS_APP['tutorial']['home_number']

Renvoie:

list of last published content

Type renvoyé:

list

transfer_paternity(unregistered_user, replacement_author, gallery_class)

Erases or transfers the paternity of all publishable content owned by a user. If a content has more than one author, the unregistering author simply leaves its author list, otherwise their published content are sent to replacement_author, unpublished content are deleted and their beta topics closed.

Paramètres:
  • unregistered_user – the user to be unregistered

  • replacement_author – the new author

  • gallery_class – the class to link tutorial with gallery (perhaps overkill :p)

class zds.tutorialv2.managers.ReactionManager(*args, **kwargs)

Custom reaction manager.

Les vues (views/)

Mixins (mixins.py)

class zds.tutorialv2.mixins.ContentTypeMixin

This class deals with the type of contents and fill context according to that

class zds.tutorialv2.mixins.DoesNotRequireValidationFormViewMixin(**kwargs)

Ensure the content do not require validation before publication.

get_form_kwargs()

Return the keyword arguments for instantiating the form.

class zds.tutorialv2.mixins.DownloadViewMixin(**kwargs)

Basic View to return a file to download

(inspired from https://djangosnippets.org/snippets/2549/ and http://stackoverflow.com/questions/16286666/send-a-file-through-django-class-based-views)

You just need to override get_contents() to make it works

get(context, **response_kwargs)

Access to a file with only get method then write the file content in response stream. Properly sets Content-Type and Content-Disposition headers

class zds.tutorialv2.mixins.FormWithPreview(**kwargs)
post(request, *args, **kwargs)

Handle POST requests: instantiate a form instance with the passed POST variables and then check if it’s valid.

class zds.tutorialv2.mixins.ModalFormView(**kwargs)

If self.modal_form is set True, this class will ensure that the redirection is made to the previous page if an error appear

form_invalid(form)

If self.modal_form is set True, this function is rewritten to send back to the previous page with an error message, instead of using the form template which is normally provided.

The redirection is made to form.previous_page_url, if exists, content:view otherwise.

exception zds.tutorialv2.mixins.MustRedirect(url, *args, **kwargs)

Exception raised when this is not the last version of the content which is called

class zds.tutorialv2.mixins.RequiresValidationViewMixin(**kwargs)

Ensure the content require validation before publication.

class zds.tutorialv2.mixins.SingleContentDetailViewMixin(**kwargs)
get_context_data(**kwargs)

Insert the single object into the context dict.

class zds.tutorialv2.mixins.SingleContentDownloadViewMixin(**kwargs)

Ensure, by rewritring get(), that - self.object contains the result of get_object() (as it must be if get() is not rewritten) - self.sha is set according to self.request.GET[“version”] (if any) and self.object.sha_draft otherwise - self.versioned_object contains the results of get_versioned_object()

get(context, **response_kwargs)

Access to a file with only get method then write the file content in response stream. Properly sets Content-Type and Content-Disposition headers

class zds.tutorialv2.mixins.SingleContentFormViewMixin(**kwargs)

This enhanced FormView ensure,

  • by surcharging dispatch(), that:
    • self.object contains the result of get_object() (as for DetailView)

    • self.versioned_object contains the results of get_versioned_object()

  • by surcharging get_context_data(), that
    • context[“content”] contains self.versioned_object

get_context_data(**kwargs)

Insert the form into the context dict.

class zds.tutorialv2.mixins.SingleContentPostMixin

Base mixin used to get content from post query

get_object(queryset=None)

Get database representation of the content by its pk, then check permissions

class zds.tutorialv2.mixins.SingleContentViewMixin

Base mixin to get only one content, and its corresponding versioned content

Deals with URL resolution in the following way:

  1. In get_object():
    • Fetch the PublishableContent according to self.kwargs['pk'], self.request.GET['pk'] or self.request.POST['pk'] (one of these have to be defined). Raise Http404 if any.

    • Then, check permissions with respect to self.must_be_author and self.authorized_for_staff (and define self.is_staff and self.is_author). Raise PermissionDenied if any.

  2. In get_versioned_object():
    • Deal with sha : assume self.object.sha_draft by default, but reset according to self.request.GET['version'], if exists. - Fetch the VersionedContent. Due to the use of self.object.load_version_or_404(sha), raise Http404.

    • Check if it’s the beta or public version, and allow access if it’s the case. Raise PermissionDenied.

    • Check slug if self.kwargs['slug'] is defined. Raise Http404 if any.

  3. In get_public_object(), fetch the last published version, if any

Any redefinition of any of these two functions should take care of those points.

get_object(queryset=None)

Get database representation of the content by its pk, then check permissions

get_public_object()

Get the published version, if any

get_versioned_object()

Gets the asked version of current content.

class zds.tutorialv2.mixins.SingleOnlineContentDetailViewMixin(**kwargs)

This enhanced DetailView ensures,

  • by rewriting get(), that:
    • self.object contains the result of get_object() (as it must be if get() was not rewritten)

    • Redirection is made if we catch MustRedirect

    • self.versioned_object contains a PublicContent object

    • self.public_content_object contains a PublishedContent object

  • by surcharging get_context_data(), that
    • context[“content”] is set

    • context[“is_staff”] is set

    • context[“can_edit”] is set

    • context[“public_object”] is set

    • context[“is_antispam”] is set

    • context[“db_content”] is set with the PublishableContent instance

get_context_data(**kwargs)

Insert the single object into the context dict.

class zds.tutorialv2.mixins.SingleOnlineContentFormViewMixin(**kwargs)

This enhanced FormView ensure,

  • by surcharging dispatch(), that:
    • self.public_content_object contains a PublishedContent object

    • self.object contains the result of get_object() (as for DetailView)

    • self.versioned_object contains the results of get_versioned_object()

  • by surcharging get_context_data(), that
    • context[“content”] is set

    • context[“public_object”] is set

Note: does not catch MustRedirect, so you should not use a slug with POST request

get_context_data(**kwargs)

Insert the form into the context dict.

class zds.tutorialv2.mixins.SingleOnlineContentViewMixin

Base mixin to get only one content online content

Deals with URL resolution in the following way:

  1. In get_object():
    • Fetch the PublicContent according to self.kwargs['pk'], self.request.GET['pk'] or self.request.POST['pk'] 0(one of these have to be defined). Raise Http404 if any.

    • Check if self.current_content_type if defined, and use it if it’s the case

    • Check if slug is defined, also check object it if it’s the case

    • Then, define self.is_staff and self.is_author.

  2. In get_versioned_object(): Fetch the VersionedContent. Due to the use of

    self.public_content_object.load_public_version_or_404(), raise Http404 if any.

Any redefinition of any of these two functions should take care of those points.

get_redirect_url(public_version)

Return the most recent url, based on the current public version

Les formulaires (forms.py)

class zds.tutorialv2.forms.AcceptValidationForm(validation, *args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.AskValidationForm(content, *args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.AuthorForm(*args, **kwargs)
clean_username()

Check every username and send it to the cleaned_data[“user”] list

Renvoie:

a dictionary of all treated data with the users key added

is_valid()

Return True if the form has no errors, or False otherwise.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.BetaForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.CancelValidationForm(validation, *args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ContainerForm(*args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ContentCompareStatsURLForm(urls, *args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ContentForm(*args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ContributionForm(content, *args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.DoNotPickOpinionForm(content, *args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

is_valid()

Return True if the form has no errors, or False otherwise.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.EditContentLicenseForm(versioned_content, *args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.EditContentTagsForm(content, db_content, *args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ExtractForm(*args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.FormWithTitle(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ImportContentForm(*args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ImportForm(*args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ImportNewContentForm(*args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.JsFiddleActivationForm(*args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.MoveElementForm(*args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.NoteEditForm(*args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.NoteForm(content, reaction, *args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.PickOpinionForm(content, *args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.PromoteOpinionToArticleForm(content, *args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.PublicationForm(content, *args, **kwargs)

The publication form (used only for content without preliminary validation).

clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.RejectValidationForm(validation, *args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.RemoveAuthorForm(*args, **kwargs)
clean_username()

Check every username and send it to the cleaned_data[“user”] list

Renvoie:

a dictionary of all treated data with the users key added

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.RemoveContributionForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.RemoveSuggestionForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ReviewerTypeModelChoiceField(queryset, *, empty_label='---------', required=True, widget=None, label=None, initial=None, help_text='', to_field_name=None, limit_choices_to=None, blank=False, **kwargs)
label_from_instance(obj)

Convert objects into strings and generate the labels for the choices presented by this object. Subclasses can override this method to customize the display of the choices.

class zds.tutorialv2.forms.RevokeValidationForm(content, *args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.SearchSuggestionForm(content, *args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.ToggleHelpForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.UnpickOpinionForm(content, *args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.UnpublicationForm(content, *args, **kwargs)
property media

Return all media required to render the widgets on this form.

class zds.tutorialv2.forms.WarnTypoForm(content, targeted, public=True, *args, **kwargs)
clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named “__all__”.

property media

Return all media required to render the widgets on this form.

Les utilitaires (utils.py)

exception zds.tutorialv2.utils.BadArchiveError(reason)

The exception that is raised when a bad archive is sent

exception zds.tutorialv2.utils.BadManifestError(*args, **kwargs)

The exception that is raised when the manifest.json contains errors

exception zds.tutorialv2.utils.InvalidOperationError
class zds.tutorialv2.utils.NamedUrl(name, url, level)
level

Alias for field number 2

name

Alias for field number 0

url

Alias for field number 1

exception zds.tutorialv2.utils.TooDeepContainerError(*args, **kwargs)

Exception used to represent the fact you can’t add a container to a level greater than two

zds.tutorialv2.utils.all_is_string_appart_from_given_keys(dict_representation, keys=('children',))

check all keys are string appart from the children key :param dict_representation: the json decoded dictionary :param keys: keys that do not need to be string :type dict_representation: dict :return: :rtype: bool

zds.tutorialv2.utils.clone_repo(old_path, new_path)

Proxy to git clone command. Ensure directory are properly created

Paramètres:
  • old_path – path of the repo to be cloned

  • new_path – path of the target repo

Renvoie:

the target repository encapsulated in a GitPython object.

Type renvoyé:

Repo

zds.tutorialv2.utils.default_slug_pool()

initialize a slug pool with all forbidden name. basically introduction and conclusion

Renvoie:

the forbidden slugs in the edition system

Type renvoyé:

dict

zds.tutorialv2.utils.export_container(container, with_text=False, ready_to_publish_only=False)

Export a container to a dictionary

Paramètres:
  • container (zds.tutorialv2.models.models_versioned.Container) – the container

  • ready_to_publish_only (boolean) – if True, returns only ready-to-publish containers

Renvoie:

dictionary containing the information

Type renvoyé:

dict

zds.tutorialv2.utils.export_content(content, with_text=False, ready_to_publish_only=False)

Export a content to dictionary in order to store them in a JSON file

Paramètres:
  • content – content to be exported

  • ready_to_publish_only (boolean) – if True, returns only ready-to-publish containers

Renvoie:

dictionary containing the information

Type renvoyé:

dict

zds.tutorialv2.utils.export_extract(extract, with_text)

Export an extract to a dictionary

Paramètres:

extract – extract to export

Renvoie:

dictionary containing the information

Type renvoyé:

dict

zds.tutorialv2.utils.fill_containers_from_json(json_sub, parent)

Function which call itself to fill container

Paramètres:
  • json_sub – dictionary from “manifest.json”

  • parent – the container to fill

Lève:
  • BadManifestError – if the manifest is not well formed or the content’s type is not correct

  • KeyError – if one mandatory key is missing

zds.tutorialv2.utils.get_blob(tree, path)

Return the data contained into a given file

Paramètres:
  • tree (git.objects.tree.Tree) – Git Tree object

  • path (str) – Path to file

Renvoie:

contains

Type renvoyé:

bytearray

zds.tutorialv2.utils.get_commit_author()

get a dictionary that represent the commit author with author and comitter key. If there is no users, bot account pk is used.

Renvoie:

correctly formatted commit author for repo.index.commit()

Type renvoyé:

dict

zds.tutorialv2.utils.get_content_from_json(json, sha, slug_last_draft, public=False, max_title_len=80, hint_licence=None)

Transform the JSON formated data into VersionedContent

Paramètres:
  • json – JSON data from a manifest.json file

  • sha – version

  • slug_last_draft – the slug for draft marked version

  • max_title_len – max str length for title

  • public – the function will fill a PublicContent instead of a VersionedContent if True

  • hint_licence – avoid loading the licence if it is already the same as the one loaded

Renvoie:

a Public/VersionedContent with all the information retrieved from JSON

Type renvoyé:

zds.tutorialv2.models.versioned.VersionedContent|zds.tutorialv2.models.database.PublishedContent

zds.tutorialv2.utils.get_target_tagged_tree(movable_child, root)

Gets the tagged tree with deplacement availability

Paramètres:
  • movable_child – the extract we want to move

  • root – the VersionedContent we use as root

Type renvoyé:

tuple

Renvoie:

an array of tuples that represent the capacity of movable_child to be moved near another child check get_target_tagged_tree_for_extract and get_target_tagged_tree_for_container for format

zds.tutorialv2.utils.get_target_tagged_tree_for_container(movable_child, root, bias=-1)

Gets the tagged tree with displacement availability when movable_child is an extract

Paramètres:
  • movable_child – the container we want to move

  • root – the VersionedContent we use as root

  • bias – a negative or zero integer that represent the level bias. A value of -1 (default) represent the fact that we want to make the movable_child a sibling of the tagged child, a value of 0 that we want to make it a sub child.

Type renvoyé:

tuple

Renvoie:

an array of tuples that represent the capacity of movable_child to be moved near another child extracts are not included

zds.tutorialv2.utils.get_target_tagged_tree_for_extract(movable_child, root)

Gets the tagged tree with displacement availability when movable_child is an extract

Paramètres:
  • movable_child – the extract we want to move

  • root – the VersionedContent we use as root

Type renvoyé:

tuple

Renvoie:

an array of tuples that represent the capacity of movable_child to be moved near another child tuples are (relative_path, title, level, can_be_a_target)

zds.tutorialv2.utils.init_new_repo(db_object, introduction_text, conclusion_text, commit_message='', do_commit=True)

Create a new repository in settings.ZDS_APP['contents']['private_repo'] to store the files for a new content. Note that db_object.sha_draft will be set to the good value

Paramètres:
  • db_objectPublishableContent (WARNING: should have a valid slug, so previously saved)

  • introduction_text – introduction from form

  • conclusion_text – conclusion from form

  • commit_message – set a commit message instead of the default one

  • do_commit – perform commit if True

Renvoie:

VersionedContent object

Type renvoyé:

zds.tutorialv2.models.versioned.VersionedContent

zds.tutorialv2.utils.mark_read(content, user=None)

Mark the last tutorial note as read for the user.

Paramètres:
  • content – the content to mark

  • user – user that read the content, if None will use currrent user

zds.tutorialv2.utils.never_read(content, user=None)

Check if a content note feed has been read by a user since its last post was added.

Paramètres:
Renvoie:

True if the user never read this content’s reactions, False otherwise

Type renvoyé:

bool

zds.tutorialv2.utils.normalize_unicode_url(unicode_url)

Sometimes you get an URL by a user that just isn’t a real URL because it contains unsafe characters like “β” and so on. This function can fix some of the problems in a similar way browsers handle data entered by the user:

normalize_unicode_url(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)')
# 'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29'
Paramètres:

charset – The target charset for the URL if the url was given as unicode string.

zds.tutorialv2.utils.search_container_or_404(base_content, kwargs_array)
Paramètres:
  • base_content – the base Publishable content we will use to retrieve the container

  • kwargs_array – an array that may contain parent_container_slug and container_slug keys or the string representation

Renvoie:

the Container object we were searching for

Type renvoyé:

zds.tutorialv2.models.versioned.Container

Lève:

Http404 – if no suitable container is found

zds.tutorialv2.utils.search_extract_or_404(base_content, kwargs_array)
Paramètres:
  • base_content – the base Publishable content we will use to retrieve the container

  • kwargs_array – an array that may contain parent_container_slug and container_slug and MUST contains extract_slug

Renvoie:

the Extract object

Type renvoyé:

zds.tutorialv2.models.versioned.Extract

Raise:

Http404 if not found

zds.tutorialv2.utils.try_adopt_new_child(adoptive_parent, child)

Try the adoptive parent to take the responsability of the child :param adoptive_parent: the new parent for child if all check pass :param child: content child to be moved :raise Http404: if adoptive_parent_full_path is not found on root hierarchy :raise TypeError: if the adoptive parent is not allowed to adopt the child due to its type :raise TooDeepContainerError: if the child is a container that is too deep to be adopted by the proposed parent

Les utilitaires de publication (publication_utils.py)

exception zds.tutorialv2.publication_utils.FailureDuringPublication(*args, **kwargs)

Exception raised if something goes wrong during publication process

class zds.tutorialv2.publication_utils.MarkdownPublicator
publish(md_file_path, base_name, *, cur_language='fr-fr', **kwargs)

Function called to generate a content export

Paramètres:
  • md_file_path – base markdown file path

  • base_name – file name without extension

  • kwargs – other publicator dependent options

class zds.tutorialv2.publication_utils.Publicator

Publicator base object, all methods must be overridden

get_published_content_entity(md_file_path) PublishedContent

Retrieve the db entity from mdfile path

Paramètres:

md_file_path (str) – mdfile path as string

Renvoie:

the db entity

Type renvoyé:

zds.tutorialv2.models.models_database.PublishedContent

publish(md_file_path, base_name, **kwargs)

Function called to generate a content export

Paramètres:
  • md_file_path – base markdown file path

  • base_name – file name without extension

  • kwargs – other publicator dependent options

class zds.tutorialv2.publication_utils.PublicatorRegistry

Register all publicator as a “human-readable name/publicator” instance key/value list

classmethod get(name)

Get publicator named “name”.

Paramètres:

name

Renvoie:

the wanted publicator

Type renvoyé:

Publicator

Lève:

KeyError – if publicator is not registered

classmethod get_all_registered(exclude=None)
Args:

exclude: A list of excluded publicator

Returns:

classmethod unregister(name)

Remove registered Publicator named “name” if present

Paramètres:

name – publicator name.

class zds.tutorialv2.publication_utils.WatchdogFilePublicator
publish(md_file_path, base_name, silently_pass=True, **kwargs)

Function called to generate a content export

Paramètres:
  • md_file_path – base markdown file path

  • base_name – file name without extension

  • kwargs – other publicator dependent options

class zds.tutorialv2.publication_utils.ZMarkdownEpubPublicator
publish(md_file_path, base_name, **kwargs)

Function called to generate a content export

Paramètres:
  • md_file_path – base markdown file path

  • base_name – file name without extension

  • kwargs – other publicator dependent options

class zds.tutorialv2.publication_utils.ZMarkdownRebberLatexPublicator(extension='.pdf', latex_classes='')

Use zmarkdown and rebber stringifier to produce latex & pdf output.

publish(md_file_path, base_name, **kwargs)

Function called to generate a content export

Paramètres:
  • md_file_path – base markdown file path

  • base_name – file name without extension

  • kwargs – other publicator dependent options

class zds.tutorialv2.publication_utils.ZipPublicator
publish(md_file_path, base_name, **kwargs)

Function called to generate a content export

Paramètres:
  • md_file_path – base markdown file path

  • base_name – file name without extension

  • kwargs – other publicator dependent options

zds.tutorialv2.publication_utils.close_article_beta(db_object, versioned, user, request=None)

Close forum topic of an article if the artcle was in beta. :param db_object: the article :type db_object: zds.tutorialv2.models.database.PublishableContent :param versioned: the public version of article, used to pupulate closing post :type versioned: zds.tutorialv2.models.versioned.VersionedContent :param user: the current user :param request: the current request

zds.tutorialv2.publication_utils.generate_external_content(base_name, extra_contents_path, md_file_path, overload_settings=False, excluded=None, **kwargs)

generate all static file that allow offline access to content

Paramètres:
  • base_name – base nae of file (without extension)

  • extra_contents_path – internal directory where all files will be pushed

  • md_file_path – bundled markdown file path

  • overload_settings – this option force the function to generate all registered formats even when settings ask for PDF not to be published

  • excluded – list of excluded format, None if no exclusion

zds.tutorialv2.publication_utils.make_zip_file(published_content)

Create the zip archive extra content from the published content

Paramètres:

published_content – a PublishedContent object

Renvoie:

zds.tutorialv2.publication_utils.publish_content(db_object, versioned, is_major_update=True)

Publish a given content.

Note

create a manifest.json without the introduction and conclusion if not needed. Also remove the “text” field of extracts.

Paramètres:
Lève:

FailureDuringPublication – if something goes wrong

Renvoie:

the published representation

Type renvoyé:

zds.tutorialv2.models.database.PublishedContent

zds.tutorialv2.publication_utils.save_validation_state(db_object, is_update, published: PublishedContent, validation, versioned, source='', is_major=False, user=None, request=None, comment='')

Save validation after publication, changes its status to ACCEPT :param db_object: the content :type db_object: zds.tutorialv2.models.database.PublishableContent :param is_update: marks if the publication is an update or a new/major publication :param published: the PublishedContent instance :param validation: the related validation :param versioned: the VersionedContent related to the public sha :param source: the optional cannonical link :param is_major: marks a major publication (first one, or new parts for example) :param user: validating user :param request: current request to get hats, and send error messages if needed

zds.tutorialv2.publication_utils.unpublish_content(db_object, moderator=None)

Remove the given content from the public view.

Note

This will send content_unpublished event.

Paramètres:
  • db_object (PublishableContent) – Database representation of the content

  • moderator (django.contrib.auth.models.User) – the staff user who triggered the unpublish action.

Renvoie:

True if unpublished, False otherwise

Type renvoyé:

bool

Les receveurs d’évènement bdd (receivers.py)

zds.tutorialv2.receivers.cleanup_validation_alerts(sender, instance, *, moderator=None, **__)

When opinions are unpublished (probably permanently), we must be sure all alerts are handled. For now we just resolve them.

Paramètres:
  • sender – sender class

  • instance – object instance

  • moderator – staff member or author that generated depublication

zds.tutorialv2.receivers.log_content_deletion(sender, instance, **__)

When a content or gallery is deleted, this action is logged.