Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit 895de2c

Browse files
committed
corrections for vsMetaFile
- corrections for encoding of INT - special treatment for movies, series and others (o-o-s).
1 parent a6739c7 commit 895de2c

30 files changed

+487
-155
lines changed

doc/FileAnalysis.xlsx

12.1 KB
Binary file not shown.

samples/film.mp4.vsmeta

129 Bytes
Binary file not shown.

samples/film2.mp4.vsmeta

34 Bytes
Binary file not shown.

samples/serie.vsmeta

114 Bytes
Binary file not shown.

samples/sonstige.mp4.vsmeta

53 Bytes
Binary file not shown.

src/tests/testvsmetaEncoder.py

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/vsmetaEncoder/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from .vsmetaBase import VsMetaBase
2+
from .vsmetaInfo import VsMetaInfo
3+
from .vsmetaInfo import VsMetaImageInfo
4+
from .vsmetaListInfo import VsMetaListInfo
5+
from .vsmetaMovieEncoder import VsMetaMovieEncoder
6+
from .vsmetaSeriesEncoder import VsMetaSeriesEncoder

src/vsmetaEncoder/vsmetaBase.py

Lines changed: 127 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
from datetime import date
22
from vsmetaEncoder.vsmetaInfo import VsMetaInfo
3+
from vsmetaEncoder.vsmetaListInfo import VsMetaListInfo
4+
from vsmetaEncoder.vsmetaImageInfo import VsMetaImageInfo
35

46
class VsMetaBase():
57

6-
TAG_FILE_HEADER = b'\x08\x02'
8+
TAG_FILE_HEADER_MOVIE = b'\x08\x01'
9+
TAG_FILE_HEADER_SERIES = b'\x08\x02'
10+
TAG_FILE_HEADER_OTHER = b'\x08\x03'
711

812
TAG_SHOW_TITLE = b'\x12'
913
TAG_SHOW_TITLE2 = b'\x1A'
@@ -44,18 +48,109 @@ class VsMetaBase():
4448

4549
def __init__(self):
4650

47-
self.encodedContent : bytes
51+
self.encodedContent = bytes()
4852
self.info = VsMetaInfo()
4953

50-
def _writeTag(self, tag : bytes, value = None, intBytes : int = 1, signed : bool = True):
54+
def encode(self, info : VsMetaInfo = None) -> bytes:
55+
56+
self.info = info
57+
self._writeEncodedContent()
58+
return self.encodedContent
59+
60+
# ------------------------------------
61+
# Write at meta file level - using methods at lower level to "really" write at file level
62+
# ------------------------------------
63+
def _writeFileHeader(self):
64+
self._writeTag( self.TAG_FILE_HEADER_OTHER )
65+
66+
def _writeShowTitle(self):
67+
self._writeTag( self.TAG_SHOW_TITLE, self.info.showTitle2 or self.info.showTitle)
68+
self._writeTag( self.TAG_SHOW_TITLE2, self.info.showTitle2 or self.info.showTitle)
69+
70+
def _writeEpisodeTitle(self):
71+
self._writeTag( self.TAG_EPISODE_TITLE, self.info.episodeTitle)
72+
73+
def _writeEpisodeDate(self):
74+
if self.info.year != 0:
75+
self._writeTag( self.TAG_YEAR, self.info.year, intBytes= 1 if self.info.year == 0 else 2)
76+
77+
if self.info.year != 0: self._writeTag( self.TAG_EPISODE_RELEASE_DATE, self.info.episodeReleaseDate)
78+
79+
def _writeEpisodeLocked(self, locked:bool=True):
80+
self._writeTag( self.TAG_EPISODE_LOCKED, locked)
81+
82+
def _writeClassification(self):
83+
self._writeTag( self.TAG_CLASSIFICATION, 0)
84+
85+
def _writeRating(self):
86+
self._writeTag( self.TAG_RATING, b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01')
87+
88+
def _writeSummary(self):
89+
if len(self.info.chapterSummary) > 0:
90+
self._writeTag(self.TAG_CHAPTER_SUMMARY, self.info.chapterSummary)
91+
92+
def _writeEncodedContent(self):
93+
# intialization only, implementation in child classes
94+
self.encodedContent = bytes() # ensure empty.
95+
96+
def _writeEpisodeMetaJSON(self):
97+
if len(self.info.episodeMetaJson) > 0:
98+
self._writeTag( self.TAG_EPISODE_META_JSON, self.info.episodeMetaJson)
99+
100+
def _writeGroup1(self):
101+
self._writeTag( self.info.TAG_GROUP1)
102+
# TODO TAG1_CAST, GENRE, DIRECTOR, WRITER
103+
104+
def _writeGroup2(self):
105+
106+
#tv show year
107+
tvshowYear = 0
108+
if(self.info.tvshowReleaseDate.year != 1900):
109+
tvshowYear = self.info.tvshowReleaseDate.year
110+
tvshowYear += 2048
111+
112+
self._writeTag( self.TAG_GROUP2)
113+
self._writeTag( b'\x01') # group 2 - occurence no. 1?
114+
#group 2 payload
115+
group2Content = bytes()
116+
group2Content += self.TAG2_SEASON + self._writeSpecialInt(self.info.season)
117+
group2Content += self.TAG2_EPISODE + self._writeSpecialInt(self.info.episode)
118+
if self.info.tvshowReleaseDate != date(1900, 1, 1):
119+
group2Content += self.TAG2_TV_SHOW_YEAR + self._writeInt(tvshowYear, 2, True)
120+
group2Content += self.TAG2_RELEASE_DATE_TV_SHOW
121+
group2Content += self._writeDate(self.info.tvshowReleaseDate)
122+
else:
123+
group2Content += self.TAG2_TV_SHOW_YEAR + self._writeInt(0, 1, True)
124+
if self.info.tvshowLocked: group2Content += self.TAG2_LOCKED + self._writeBool(True)
125+
if len(self.info.tvshowMetaJson) > 0:
126+
group2Content += self.TAG2_TVSHOW_META_JSON
127+
group2Content += self._writeStr(self.info.tvshowMetaJson)
128+
129+
group2Content = len(group2Content).to_bytes(1, 'big') + group2Content # length of group 2 payload
130+
131+
self.encodedContent += group2Content
132+
133+
# TODO tvshowsummary,
134+
# TODO tvshowposter, md5, tv_show_metajson
135+
self._writeGroup3
136+
137+
def _writeGroup3(self, info: VsMetaInfo):
138+
pass
139+
# TODO tvshowBackdrop, MD5, timestamp
140+
141+
# ------------------------------------
142+
# Write at file level
143+
# ------------------------------------
144+
145+
def _writeTag(self, tag : bytes, value = None, intBytes : int = 0, signed : bool = True):
51146

52147
#write tag
53148
self.encodedContent += self._writeBinary(tag)
54149
if value is None: return
55150

56151
#write content
57152
if (type(value) == str): self.encodedContent += self._writeStr(value)
58-
if (type(value) == int): self.encodedContent += self._writeInt(value, intBytes, signed)
153+
if (type(value) == int): self.encodedContent += self._writeSpecialInt(value)
59154
if (type(value) == date): self.encodedContent += self._writeDate(value)
60155
if (type(value) == bool): self.encodedContent += self._writeBool(value)
61156
if (type(value) == bytes): self.encodedContent += self._writeBinary(value)
@@ -79,13 +174,22 @@ def _writeStr(self, text : str, withBOM : bool = False) -> bytes:
79174
textAsByte = bytes( text, encoding )
80175

81176
returnValue = bytes()
82-
returnValue += len(textAsByte).to_bytes(1, 'big')
177+
lengthTByte = len(textAsByte)
178+
returnValue += self._writeSpecialInt(lengthTByte)
83179
returnValue += textAsByte
84180
return returnValue
85181

86-
def _writeInt(self, numberValue : int = 0, bytesToUse : int = 1, signed : bool = True) -> bytes:
182+
def _writeInt(self, numberValue : int = 0, bytesToUse : int = 0, signed : bool = True) -> bytes:
87183

88184
returnValue = bytes()
185+
186+
# ok, the following looks very pragmatic...
187+
if bytesToUse == 0:
188+
bytesToUse = 1
189+
if numberValue >= (2**(1*8)): bytesToUse = 2
190+
if numberValue >= (2**16): bytesToUse = 3
191+
if numberValue >= (2**24): bytesToUse = 4
192+
89193
returnValue += numberValue.to_bytes(bytesToUse, byteorder="little", signed=signed)
90194
return returnValue
91195

@@ -95,3 +199,20 @@ def _writeDate(self, dateValue : date) -> bytes:
95199
returnValue += b'\x0a' # length of date field, x0a = 10
96200
returnValue += bytes(dateValue.strftime("%Y-%m-%d"), 'utf-8' )
97201
return returnValue
202+
203+
def _writeSpecialInt(self, valueI:int) -> bytes:
204+
205+
returnValue = b''
206+
num = valueI
207+
hasMore = True
208+
209+
while hasMore:
210+
211+
value1 = (num & 0b01111111)
212+
num = num >> 7
213+
hasMore = False if num == 0 else True
214+
value2 = 0x80 if hasMore else 0x00
215+
216+
returnValue += (value1 | value2).to_bytes(1, 'little')
217+
218+
return returnValue

src/vsmetaEncoder/vsmetaEncoder.py

Lines changed: 0 additions & 81 deletions
This file was deleted.

src/vsmetaEncoder/vsmetaInfo.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1-
from datetime import date
1+
from datetime import date, datetime
22
from vsmetaEncoder.vsmetaListInfo import VsMetaListInfo
33
from vsmetaEncoder.vsmetaImageInfo import VsMetaImageInfo
44

5+
6+
# TODO get rid of class
57
class VsMetaInfo():
68
def __init__(self):
9+
710
self.showTitle = ""
811
self.showTitle2 = ""
912
self.episodeTitle = ""
13+
1014
self.year = 0
1115
self.episodeReleaseDate = date(1900, 1, 1)
12-
self.tvshowReleaseDate = date(1900, 1, 1)
16+
1317
self.tvshowYear = 0
18+
self.tvshowReleaseDate = date(1900, 1, 1)
19+
1420
self.tvshowSummary = ""
1521
self.chapterSummary = ""
1622
self.classification = 0
@@ -22,5 +28,13 @@ def __init__(self):
2228
self.episodeMetaJson = ""
2329
self.tvshowMetaJson = ""
2430
self.timestamp = date(1900, 1, 1)
25-
self.episodeLocked = False
26-
self.tvshowLocked = False
31+
self.episodeLocked = True
32+
self.tvshowLocked = True
33+
34+
def setEpisodeDate(self, episodeDate: date):
35+
self.episodeReleaseDate = episodeDate
36+
self.year = episodeDate.year
37+
38+
def setShowDate(self, showDate: date):
39+
self.tvshowReleaseDate = showDate
40+
self.tvshowYear = showDate.year

0 commit comments

Comments
 (0)