Skip to content

Commit

Permalink
[#147] Renamed the Link class to File.
Browse files Browse the repository at this point in the history
  • Loading branch information
eoyilmaz committed Jan 13, 2025
1 parent 575b576 commit 129e3a2
Show file tree
Hide file tree
Showing 24 changed files with 673 additions and 672 deletions.
8 changes: 4 additions & 4 deletions src/stalker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from stalker.models.department import Department, DepartmentUser
from stalker.models.entity import Entity, EntityGroup, SimpleEntity
from stalker.models.format import ImageFormat
from stalker.models.link import Link
from stalker.models.link import File
from stalker.models.message import Message
from stalker.models.mixins import (
ACLMixin,
Expand All @@ -46,7 +46,7 @@
ProjectUser,
)
from stalker.models.repository import Repository
from stalker.models.review import Daily, DailyLink, Review
from stalker.models.review import Daily, DailyFile, Review
from stalker.models.scene import Scene
from stalker.models.schedulers import SchedulerBase, TaskJugglerScheduler
from stalker.models.sequence import Sequence
Expand Down Expand Up @@ -75,19 +75,19 @@
"CodeMixin",
"DAGMixin",
"Daily",
"DailyLink",
"DailyFile",
"DateRangeMixin",
"Department",
"DepartmentUser",
"Entity",
"EntityGroup",
"EntityType",
"File",
"FilenameTemplate",
"Good",
"Group",
"ImageFormat",
"Invoice",
"Link",
"LocalSession",
"Message",
"Note",
Expand Down
2 changes: 1 addition & 1 deletion src/stalker/db/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ def init() -> None:
"Department",
"Entity",
"EntityGroup",
"File",
"FilenameTemplate",
"Good",
"Group",
"ImageFormat",
"Invoice",
"Link",
"Message",
"Note",
"Page",
Expand Down
33 changes: 17 additions & 16 deletions src/stalker/models/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

if TYPE_CHECKING: # pragma: no cover
from stalker.models.auth import User
from stalker.models.link import Link
from stalker.models.link import File
from stalker.models.note import Note
from stalker.models.tag import Tag
from stalker.models.type import Type
Expand Down Expand Up @@ -198,11 +198,11 @@ class attribute to control auto naming behavior.
)

thumbnail_id: Mapped[Optional[int]] = mapped_column(
ForeignKey("Links.id", use_alter=True, name="z")
ForeignKey("Files.id", use_alter=True, name="z")
)

thumbnail: Mapped[Optional["Link"]] = relationship(
primaryjoin="SimpleEntities.c.thumbnail_id==Links.c.id",
thumbnail: Mapped[Optional["File"]] = relationship(
primaryjoin="SimpleEntities.c.thumbnail_id==Files.c.id",
post_update=True,
)

Expand All @@ -225,7 +225,7 @@ def __init__(
updated_by: Optional["User"] = None,
date_created: Optional[datetime] = None,
date_updated: Optional[datetime] = None,
thumbnail: Optional["Link"] = None,
thumbnail: Optional["File"] = None,
html_style: Optional[str] = "",
html_class: Optional[str] = "",
**kwargs: Optional[Dict[str, Any]],
Expand Down Expand Up @@ -617,26 +617,27 @@ def _validate_type(self, key: str, type_: "Type") -> "Type":
return type_

@validates("thumbnail")
def _validate_thumbnail(self, key: str, thumb: "Link") -> "Link":
def _validate_thumbnail(self, key: str, thumb: "File") -> "File":
"""Validate the given thumb value.
Args:
key (str): The name of the validated column.
thumb (Link): The thumb value to be validated.
thumb (File): The thumb value to be validated.
Raises:
TypeError: If the given thumb value is not None and not a Link instance.
TypeError: If the given thumb value is not None and not a File
instance.
Returns:
Union[None, Link]: The validated thumb value.
Union[None, File]: The validated thumb value.
"""
if thumb is not None:
from stalker import Link
from stalker import File

if not isinstance(thumb, Link):
if not isinstance(thumb, File):
raise TypeError(
f"{self.__class__.__name__}.thumbnail should be a "
"stalker.models.link.Link instance, "
"stalker.models.link.File instance, "
f"not {thumb.__class__.__name__}: '{thumb}'"
)
return thumb
Expand Down Expand Up @@ -682,8 +683,8 @@ def _validate_html_style(self, key: str, html_style: str) -> str:

if not isinstance(html_style, str):
raise TypeError(
f"{self.__class__.__name__}.html_style should be a basestring "
f"instance, not {html_style.__class__.__name__}: '{html_style}'"
f"{self.__class__.__name__}.html_style should be a str, "
f"not {html_style.__class__.__name__}: '{html_style}'"
)
return html_style

Expand All @@ -706,8 +707,8 @@ def _validate_html_class(self, key: str, html_class: str) -> str:

if not isinstance(html_class, str):
raise TypeError(
f"{self.__class__.__name__}.html_class should be a basestring "
f"instance, not {html_class.__class__.__name__}: '{html_class}'"
f"{self.__class__.__name__}.html_class should be a str, "
f"not {html_class.__class__.__name__}: '{html_class}'"
)
return html_class

Expand Down
73 changes: 37 additions & 36 deletions src/stalker/models/link.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
"""Link related classes and utility functions are situated here."""
"""File related classes and utility functions are situated here."""

import os
from typing import Any, Dict, Optional, Union
Expand All @@ -13,51 +13,52 @@
logger = get_logger(__name__)


class Link(Entity):
"""Holds data about external links.
class File(Entity):
"""Holds data about external files or file sequences.
Links are all about giving some external information to the current entity (external
to the database, so it can be something on the :class:`.Repository` or in the Web or
anywhere that the server can reach). The type of the link (general, file, folder,
web page, image, image sequence, video, movie, sound, text etc.) can be defined by a
:class:`.Type` instance (you can also use multiple :class:`.Tag` instances to add
more information, and to filter them back). Again it is defined by the needs of the
studio.
Files are all about giving some external information to the current entity
(external to the database, so it can be something on the
:class:`.Repository` or in the Web or anywhere that the server can reach).
The type of the file (general, file, folder, web page, image, image
sequence, video, movie, sound, text etc.) can be defined by a
:class:`.Type` instance (you can also use multiple :class:`.Tag` instances
to add more information, and to filter them back). Again it is defined by
the needs of the studio.
For sequences of files the file name should be in "%h%p%t %R" format in PySeq_
formatting rules.
For sequences of files the file name should be in "%h%p%t %R" format in
PySeq_ formatting rules.
There are three secondary attributes (properties to be more precise) ``path``,
``filename`` and ``extension``. These attributes are derived from the
:attr:`.full_path` attribute and they modify it.
There are three secondary attributes (properties to be more precise)
``path``, ``filename`` and ``extension``. These attributes are derived from
the :attr:`.full_path` attribute and they modify it.
Path
It is the path part of the full_path
It is the path part of the full_path.
Filename
It is the filename part of the full_path, also includes the extension, so
changing the filename also changes the extension part.
It is the filename part of the full_path, also includes the extension,
so changing the filename also changes the extension part.
Extension
It is the extension part of the full_path. It also includes the extension
separator ('.' for most of the file systems).
It is the extension part of the full_path. It also includes the
extension separator ('.' for most of the file systems).
Args:
full_path (str): The full path to the link, it can be a path to a folder or a
file in the file system, or a web page. For file sequences use "%h%p%t %R"
format, for more information see `PySeq Documentation`_. It can be set to
empty string (or None which will be converted to an empty string
automatically).
full_path (str): The full path to the File, it can be a path to a
folder or a file in the file system, or a web page. For file
sequences use "%h%p%t %R" format, for more information see
`PySeq Documentation`_. It can be set to empty string (or None
which will be converted to an empty string automatically).
.. _PySeq: http://packages.python.org/pyseq/
.. _PySeq Documentation: http://packages.python.org/pyseq/
"""

__auto_name__ = True
__tablename__ = "Links"
__mapper_args__ = {"polymorphic_identity": "Link"}
__tablename__ = "Files"
__mapper_args__ = {"polymorphic_identity": "File"}

link_id: Mapped[int] = mapped_column(
file_id: Mapped[int] = mapped_column(
"id",
ForeignKey("Entities.id"),
primary_key=True,
Expand All @@ -67,7 +68,7 @@ class Link(Entity):
original_filename: Mapped[Optional[str]] = mapped_column(String(256))
# file systems
full_path: Mapped[Optional[str]] = mapped_column(
Text, doc="The full path of the url to the link."
Text, doc="The full path of the url to the file."
)

def __init__(
Expand All @@ -76,7 +77,7 @@ def __init__(
original_filename: Optional[str] = "",
**kwargs: Optional[Dict[str, Any]],
) -> None:
super(Link, self).__init__(**kwargs)
super(File, self).__init__(**kwargs)
self.full_path = full_path
self.original_filename = original_filename

Expand Down Expand Up @@ -255,18 +256,18 @@ def extension(self, extension: Union[None, str]) -> None:
self.filename = os.path.splitext(self.filename)[0] + extension

def __eq__(self, other: Any) -> bool:
"""Check if the other is equal to this Link.
"""Check if the other is equal to this File.
Args:
other (Any): The other object to be checked for equality.
Returns:
bool: If the other object is a Link instance and has the same full_path and
type value.
bool: If the other object is a File instance and has the same
full_path and type value.
"""
return (
super(Link, self).__eq__(other)
and isinstance(other, Link)
super(File, self).__eq__(other)
and isinstance(other, File)
and self.full_path == other.full_path
and self.type == other.type
)
Expand All @@ -279,4 +280,4 @@ def __hash__(self) -> int:
Returns:
int: The hash value.
"""
return super(Link, self).__hash__()
return super(File, self).__hash__()
30 changes: 15 additions & 15 deletions src/stalker/models/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from stalker.models.auth import Permission
from stalker.models.project import Project
from stalker.models.status import Status, StatusList
from stalker.models.link import Link
from stalker.models.link import File
from stalker.models.studio import WorkingHours


Expand Down Expand Up @@ -1042,28 +1042,28 @@ def _validate_project(self, key: str, project: "Project") -> "Project":
class ReferenceMixin(object):
"""Adds reference capabilities to the mixed in class.
References are :class:`stalker.models.link.Link` instances or anything
References are :class:`stalker.models.link.File` instances or anything
derived from it, which adds information to the attached objects. The aim of
the References are generally to give more info to direct the evolution of
the object.
Args:
references (Link): A list of :class:`.Link` instances.
references (File): A list of :class:`.File` instances.
"""

# add this lines for Sphinx
# __tablename__ = "ReferenceMixins"

def __init__(
self, references: Optional[List["Link"]] = None, **kwargs: Dict[str, Any]
self, references: Optional[List["File"]] = None, **kwargs: Dict[str, Any]
) -> None:
if references is None:
references = []

self.references = references

@declared_attr
def references(cls) -> Mapped[Optional[List["Link"]]]:
def references(cls) -> Mapped[Optional[List["File"]]]:
"""Create the references attribute as a declared attribute.
Returns:
Expand All @@ -1072,40 +1072,40 @@ def references(cls) -> Mapped[Optional[List["Link"]]]:
# get secondary table
secondary_table = create_secondary_table(
cls.__name__,
"Link",
"File",
cls.__tablename__,
"Links",
"Files",
f"{cls.__name__}_References",
)
# return the relationship
return relationship(
secondary=secondary_table,
doc="""A list of :class:`.Link` instances given as a reference for
doc="""A list of :class:`.File` instances given as a reference for
this entity.
""",
)

@validates("references")
def _validate_references(self, key: str, reference: "Link") -> "Link":
def _validate_references(self, key: str, reference: "File") -> "File":
"""Validate the given reference.
Args:
key (str): The name of the validated column.
reference (Link): The reference value to be validated.
reference (File): The reference value to be validated.
Raises:
TypeError: If the reference is not a Link instance.
TypeError: If the reference is not a File instance.
Returns:
Link: The validated reference value.
File: The validated reference value.
"""
from stalker.models.link import Link
from stalker.models.link import File

# all the items should be instance of stalker.models.entity.Entity
if not isinstance(reference, Link):
if not isinstance(reference, File):
raise TypeError(
f"All the items in the {self.__class__.__name__}.references should "
"be stalker.models.link.Link instances, "
"be stalker.models.link.File instances, "
f"not {reference.__class__.__name__}: '{reference}'"
)
return reference
Expand Down
2 changes: 1 addition & 1 deletion src/stalker/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class Project(Entity, ReferenceMixin, StatusMixin, DateRangeMixin, CodeMixin):
Deleting a :class:`.Project` instance will cascade the delete operation to
all the :class:`.Task` s related to that particular Project and it will
cascade the delete operation to :class:`.TimeLog` s, :class:`.Version` s,
:class:`.Link` s and :class:`.Review` s etc.. So one can delete a
:class:`.File` s and :class:`.Review` s etc.. So one can delete a
:class:`.Project` instance without worrying about the non-project related
data like :class:`.User` s or :class:`.Department` s to be deleted.
Expand Down
Loading

0 comments on commit 129e3a2

Please sign in to comment.