refactorizar la web, empezar con subtítulos tipo karaoke, afinar un poco chiquilla

This commit is contained in:
Ales (Shagi) Zabala Alava 2020-09-21 20:14:10 +02:00
parent 56cfb0ca9a
commit 0e03c918de
21 changed files with 9294 additions and 157 deletions

View File

@ -0,0 +1,48 @@
[Script Info]
ScriptType: v4.00+
PlayResX: 480
PlayResY: 360
WrapStyle: 0
ScaledBorderAndShadow: yes
Title: Default Aegisub file
YCbCr Matrix: TV.601
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code once,function char_counter(ref) ci[ref] = ci[ref] + 1; return "" end
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code line all,ci = {0,0}; delay = 800; delay_2 = 300
Comment: 1,0:00:00.00,0:00:00.00,Default,,0,0,0,template char,!char_counter(1)!!retime("start2syl",-1500+(ci[1]-1)*50,0)!{\an8\alpha&HAF\fscx50\fscy50\bord1\3c&HFFFFFF&\1c&HFFFFFF&\blur1\t(!$scenter-$lleft+200!,!$scenter!,\fscx120\fscy120\alpha&0&)\pos($scenter,$smiddle)\fscx100\fscy100\shad0}
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl,!retime("syl",0,0)!{\an2\pos($center, !$smiddle - 5!)\fscx100\fscy100\c&HFFFFFF&\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\blur5\bord2\t(0,!$dur*0.5!,\frz!math.random(-30,30)!)\t(!$dur*0.5!,$dur,\frz0)\t(0,300,\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\c&HFFFFFF&\bord5\blur6)\t(300,$dur,\c\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\bord2\blur1)}
Dialogue: 0,0:00:49.00,0:00:52.00,Default,,0,0,0,,{\k29}Ten{\k56}go{\k65} {\k28}un {\k122}404
Dialogue: 0,0:00:52.00,0:00:54.90,Default,,0,0,0,,{\k39}en {\k42}el{\k82} {\k22}na{\k14}ve{\k12}ga{\k79}dor
Dialogue: 0,0:00:55.00,0:00:59.00,Default,,0,0,0,,{\k32}fo{\k54}tos,{\k81} {\k22}au{\k28}dios, {\k25}vi{\k11}deos, {\k29}do{\k20}cu{\k27}men{\k71}tos
Dialogue: 0,0:00:59.50,0:01:00.70,Default,,0,0,0,,{\k34}to{\k17}do {\k17}vo{\k52}ló
Dialogue: 0,0:01:01.00,0:01:04.00,Default,,0,0,0,,{\k40}ve{\k20}o{\k97} {\k42}car{\k30}pe{\k18}tas {\k18}va{\k20}cí{\k15}as
Dialogue: 0,0:01:04.00,0:01:07.00,Default,,0,0,0,,{\k30}na{\k24}da {\k28}en{\k90} {\k23}su in{\k35}te{\k70}rior
Dialogue: 0,0:01:07.00,0:01:10.00,Default,,0,0,0,,{\k38}pien{\k40}sas{\k78} {\k38}que {\k35}co{\k19}ño ha {\k17}pa{\k17}sa{\k18}do
Dialogue: 0,0:01:10.00,0:01:13.00,Default,,0,0,0,,{\k42}bus{\k48}cas{\k81} {\k31}al{\k23}go {\k22}que{\k13}da{\k40}rá
Dialogue: 0,0:01:25.00,0:01:28.00,Default,,0,0,0,,{\k39}te{\k59}nía{\k80} {\k27}un {\k32}ma{\k16}zo {\k17}de {\k9}co{\k21}sas
Dialogue: 0,0:01:28.00,0:01:31.00,Default,,0,0,0,,{\k46}fli{\k38}pas,{\k97} {\k38}con {\k19}lo {\k22}que {\k17}per{\k23}dí
Dialogue: 0,0:01:31.00,0:01:34.00,Default,,0,0,0,,{\k48}bus{\k43}cas{\k88} {\k27}al{\k32}guien {\k17}que {\k11}se {\k10}en{\k10}ro{\k14}lle
Dialogue: 0,0:01:34.00,0:01:37.00,Default,,0,0,0,,{\k51}pa{\k34}ra{\k79} {\k40}ba{\k36}jar {\k14}al{\k13}go {\k33}de él
Dialogue: 0,0:01:39.00,0:01:40.40,Default,,0,0,0,,{\k37}y {\k11}te {\k12}han {\k17}jo{\k12}di{\k51}do
Dialogue: 0,0:01:42.00,0:01:43.80,Default,,0,0,0,,{\k46}y {\k9}te {\k8}han {\k19}jo{\k9}di{\k24}do {\k65}bien
Dialogue: 0,0:01:45.00,0:01:46.30,Default,,0,0,0,,{\k42}y {\k11}te {\k14}han {\k19}jo{\k13}di{\k31}do
Dialogue: 0,0:01:47.50,0:01:48.50,Default,,0,0,0,,{\k36}bien {\k14}jo{\k11}di{\k39}do!
Dialogue: 0,0:02:28.50,0:02:31.60,Default,,0,0,0,,{\k59}sien{\k55}tes{\k72} {\k18}u{\k23}na {\k12}pe{\k18}na {\k11}muy {\k28}fuer{\k14}te
Dialogue: 0,0:02:31.60,0:02:34.50,Default,,0,0,0,,{\k45}cuan{\k22}do{\k107} {\k22}ya {\k14}no {\k18}esta {\k62}allí
Dialogue: 0,0:02:34.50,0:02:37.50,Default,,0,0,0,,{\k32}y {\k47}es {\k47}por{\k59} {\k49}ese {\k41}back{\k25}up
Dialogue: 0,0:02:37.50,0:02:40.50,Default,,0,0,0,,{\k35}que {\k38}nun{\k116}ca {\k9}lle{\k13}gué{\k18} a ha{\k71}cer
Dialogue: 0,0:02:42.50,0:02:43.70,Default,,0,0,0,,{\k33}te {\k17}han {\k20}jo{\k12}di{\k38}do
Dialogue: 0,0:02:45.50,0:02:47.10,Default,,0,0,0,,{\k35}te {\k22}han {\k15}jo{\k8}di{\k24}do {\k56}bien
Dialogue: 0,0:02:48.50,0:02:49.70,Default,,0,0,0,,{\k30}te {\k20}han {\k17}jo{\k9}di{\k44}do
Dialogue: 0,0:02:51.45,0:02:52.95,Default,,0,0,0,,{\k36}te {\k15}han {\k23}jo{\k7}di{\k14}do {\k55}bien
Dialogue: 0,0:02:54.50,0:02:55.60,Default,,0,0,0,,{\k31}te {\k20}han {\k17}jo{\k12}di{\k30}do
Dialogue: 0,0:02:57.50,0:02:59.00,Default,,0,0,0,,{\k31}te {\k16}han {\k19}jo{\k15}di{\k11}do {\k58}bien
Dialogue: 0,0:03:00.50,0:03:01.50,Default,,0,0,0,,{\k32}te {\k14}han {\k18}jo{\k18}di{\k18}do
Dialogue: 0,0:03:01.50,0:03:05.50,Default,,0,0,0,,{\k37}por {\k22}te{\k33}ner{\k33}lo {\k33}ahi {\k20}su{\k16}bi{\k206}do!

View File

@ -10,18 +10,18 @@ PlayResX: 900
PlayResY: 720
[Aegisub Project Garbage]
Audio File: chiquilla.mkv
Video File: chiquilla.mkv
Audio File: chiquilla.mp4
Video File: chiquilla.mp4
Video AR Mode: 4
Video AR Value: 1.250000
Video Zoom Percent: 0.500000
Scroll Position: 33
Active Line: 36
Scroll Position: 31
Active Line: 37
Video Position: 3538
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,CyrBit,48,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1
Style: Default,CyrBit,30,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
@ -58,10 +58,10 @@ Dialogue: 0,0:01:55.80,0:01:58.10,Default,,0,0,0,,{\k14}pues {\k14}mi {\k17}chi{
Dialogue: 0,0:01:58.10,0:02:00.70,Default,,0,0,0,,{\k28}del {\k33}in{\k33}ter{\k60}ne{\k106}te.
Dialogue: 0,0:02:01.40,0:02:04.00,Default,,0,0,0,,{\k16}Y{\k11} e{\k19}lla {\k21}me {\k32}di{\k161}ce...
Dialogue: 0,0:02:07.00,0:02:11.70,Default,,0,0,0,,{\k24}que {\k28}ella {\k82}no,{\k98} {\k16}se {\k20}ins{\k38}ta{\k36}lo {\k37}na{\k91}da...
Dialogue: 0,0:02:13.00,0:02:15.70,Default,,0,0,0,,{\k31}Pe{\k13}ro {\k31}to{\k29}dos {\k31}los {\k43}tro{\k30}ya{\k62}nos
Dialogue: 0,0:02:15.90,0:02:18.30,Default,,0,0,0,,{\k33}se {\k17}ri{\k26}en {\k22}a {\k49}mis {\k26}es{\k27}pal{\k40}das
Dialogue: 0,0:02:18.30,0:02:21.50,Default,,0,0,0,,{\k35}por{\k47}que {\k36}to{\k31}dos {\k28}los {\k41}tro{\k34}ya{\k68}nos
Dialogue: 0,0:02:21.50,0:02:24.50,Default,,0,0,0,,{\k41}se {\k22}ri{\k34}en {\k47}a {\k22}mis {\k19}es{\k41}pal{\k74}das
Dialogue: 0,0:02:13.00,0:02:15.70,Default,,0,0,0,,{\k10}y{\k21} a{\k13}pa{\k31}gan{\k29}do {\k31}su {\k43}or{\k30}de{\k62}na
Dialogue: 0,0:02:15.90,0:02:18.30,Default,,0,0,0,,{\k12}se{\k21} a{\k17}ca{\k26}ban {\k22}tos {\k49}mis {\k26}pro{\k27}ble{\k40}mas
Dialogue: 0,0:02:18.30,0:02:21.50,Default,,0,0,0,,{\k35}y a{\k47}pa{\k36}gan{\k31}do {\k28}su {\k41}or{\k34}de{\k68}na
Dialogue: 0,0:02:21.50,0:02:24.50,Default,,0,0,0,,{\k41}se a{\k22}ca{\k34}ban {\k47}tos {\k22}mis {\k19}pro{\k41}ble{\k74}mas
Dialogue: 0,0:02:24.50,0:02:27.20,Default,,0,0,0,,Y yo la quiero...
Dialogue: 0,0:02:30.00,0:02:34.80,Default,,0,0,0,,Como el sol a la mañana...
Dialogue: 0,0:02:35.30,0:02:38.30,Default,,0,0,0,,Como los rayos de luz

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,172 @@
1
00:00:18,000 --> 00:00:20,500
Por la mañana yo me levanto
2
00:00:20,700 --> 00:00:23,300
y voy corriendo desde mi cama
3
00:00:23,600 --> 00:00:26,200
para ver que no hay ninguna alerta
4
00:00:26,200 --> 00:00:28,800
en mi pantalla
5
00:00:29,500 --> 00:00:32,100
Porque yo llevo tol día sufriendo
6
00:00:32,100 --> 00:00:34,900
Y es que no se conecta nada
7
00:00:35,000 --> 00:00:37,800
Y es que alguien se esta comiendo
8
00:00:37,800 --> 00:00:40,400
tol ancho de banda
9
00:00:40,900 --> 00:00:43,500
Tengo los routers que arden por dentro
10
00:00:43,600 --> 00:00:46,200
que me saltan todas las alarmas
11
00:00:46,300 --> 00:00:49,100
Ay que no sea culpa del ordena
12
00:00:49,100 --> 00:00:51,700
de esa pringada
13
00:00:52,500 --> 00:00:55,500
Y yo le digo,
14
00:00:58,100 --> 00:01:02,700
que no se instale nada!
15
00:01:04,100 --> 00:01:07,000
luego todos sus troyanos
16
00:01:07,100 --> 00:01:09,400
se rien a mis espaldas
17
00:01:09,400 --> 00:01:12,400
luego todos sus troyanos
18
00:01:12,500 --> 00:01:15,000
se rien a mis espaldas
19
00:01:15,150 --> 00:01:16,550
ay! chiquilla!
20
00:01:27,000 --> 00:01:29,600
con ese postit en la pantalla
21
00:01:29,800 --> 00:01:32,400
no entiende cosas que son tan claras
22
00:01:32,600 --> 00:01:35,200
que yo no puedo no puedo no puedo
23
00:01:35,300 --> 00:01:37,900
volver a explicarlas
24
00:01:38,000 --> 00:01:41,000
Y yo le tengo que decir pronto
25
00:01:41,300 --> 00:01:43,900
que no enchufe USBs de fuera
26
00:01:44,000 --> 00:01:46,600
porque sus bromas se llevan el tiempo
27
00:01:46,700 --> 00:01:49,300
de tres currelas.
28
00:01:49,900 --> 00:01:52,400
hasta los backups se quedan cortos
29
00:01:52,400 --> 00:01:55,400
para guardar todo lo que tiene,
30
00:01:55,800 --> 00:01:58,100
pues mi chiquilla es lo más pirata
31
00:01:58,100 --> 00:02:00,700
del internete.
32
00:02:01,400 --> 00:02:04,000
Y ella me dice...
33
00:02:07,000 --> 00:02:11,700
que ella no, se instalo nada...
34
00:02:13,000 --> 00:02:15,700
y apagando su ordena
35
00:02:15,900 --> 00:02:18,300
se acaban tos mis problemas
36
00:02:18,300 --> 00:02:21,500
y apagando su ordena
37
00:02:21,500 --> 00:02:24,500
se acaban tos mis problemas
38
00:02:24,500 --> 00:02:27,200
Y yo la quiero...
39
00:02:30,000 --> 00:02:34,800
Como el sol a la mañana...
40
00:02:35,300 --> 00:02:38,300
Como los rayos de luz
41
00:02:38,300 --> 00:02:41,300
a mi ventana yo la quiero.
42
00:02:41,300 --> 00:02:44,200
Como los rayos de luz
43
00:02:44,200 --> 00:02:48,600
a mi ventana, ay chiquilla!

View File

@ -0,0 +1,64 @@
¡Chiquilla!
Por la mañana yo me levanto
y voy corriendo desde mi cama
para ver que no haya ninguna alerta
en mi pantalla
Porque yo llevo tol día sufriendo
Y es que no se conecta nada
Y es que alguien se esta comiendo
el ancho de banda
Tengo los routers que arden por dentro
Que no me dejan enrutar nada
Ay que no sea por otro programa
de esa pringada
Y yo le digo,
que no se instale nada!
luego todos sus troyanos
se rien a mis espaldas
ay! chiquilla!
con ese postit en la pantalla
me niega cosas que son tan claras
que yo no puedo no puedo no puedo
volver a explicarlas
Y yo le tengo que decir pronto
que no enchufe USBs de fuera
es que sus bromas se llevan el tiempo
de tres currelas.
hasta los backups se quedan cortos
para guardar todo lo que tiene,
pues mi chiquilla es lo más pirata
del internete.
Y yo la miro...
Y ella no me dice nada...
Pero sus dos ojos negros
se me clavan como espadas.
Pero sus dos ojos negros
se me clavan como espadas.
Y yo la quiero...
Como el sol a la mañana...
Como los rayos de luz
a mi ventana yo la quiero.
Como los rayos de luz
a mi ventana, ay chiquilla!
https://www.youtube.com/watch?v=-d3mZmP_me4
y ella no, se instalo nadaaaa, ya!
pero con sus ojos tierno
dice que no ha tocado nada
pero con dos ojos tiernos
dice que no ha tocado nada
ay chiquilla!

View File

@ -0,0 +1,130 @@
WEBVTT
00:00:18.000 --> 00:00:20.500
Por la mañana yo me levanto
00:00:20.700 --> 00:00:23.300
y voy corriendo desde mi cama
00:00:23.600 --> 00:00:26.200
para ver que no hay ninguna alerta
00:00:26.200 --> 00:00:28.800
en mi pantalla
00:00:29.500 --> 00:00:32.100
Porque yo llevo tol día sufriendo
00:00:32.100 --> 00:00:34.900
Y es que no se conecta nada
00:00:35.000 --> 00:00:37.800
Y es que alguien se esta comiendo
00:00:37.800 --> 00:00:40.400
tol ancho de banda
00:00:40.900 --> 00:00:43.500
Tengo los routers que arden por dentro
00:00:43.600 --> 00:00:46.200
que me saltan todas las alarmas
00:00:46.300 --> 00:00:49.100
Ay que no sea culpa del ordena
00:00:49.100 --> 00:00:51.700
de esa pringada
00:00:52.500 --> 00:00:55.500
Y yo le digo,
00:00:58.100 --> 00:01:02.700
que no se instale nada!
00:01:04.100 --> 00:01:07.000
luego todos sus troyanos
00:01:07.100 --> 00:01:09.400
se rien a mis espaldas
00:01:09.400 --> 00:01:12.400
luego todos sus troyanos
00:01:12.500 --> 00:01:15.000
se rien a mis espaldas
00:01:15.150 --> 00:01:16.550
ay! chiquilla!
00:01:27.000 --> 00:01:29.600
con ese postit en la pantalla
00:01:29.800 --> 00:01:32.400
no entiende cosas que son tan claras
00:01:32.600 --> 00:01:35.200
que yo no puedo no puedo no puedo
00:01:35.300 --> 00:01:37.900
volver a explicarlas
00:01:38.000 --> 00:01:41.000
Y yo le tengo que decir pronto
00:01:41.300 --> 00:01:43.900
que no enchufe USBs de fuera
00:01:44.000 --> 00:01:46.600
porque sus bromas se llevan el tiempo
00:01:46.700 --> 00:01:49.300
de tres currelas.
00:01:49.900 --> 00:01:52.400
hasta los backups se quedan cortos
00:01:52.400 --> 00:01:55.400
para guardar todo lo que tiene,
00:01:55.800 --> 00:01:58.100
pues mi chiquilla es lo más pirata
00:01:58.100 --> 00:02:00.700
del internete.
00:02:01.400 --> 00:02:04.000
Y ella me dice...
00:02:07.000 --> 00:02:11.700
que ella no, se instalo nada...
00:02:13.000 --> 00:02:15.700
y apagando su ordena
00:02:15.900 --> 00:02:18.300
se acaban tos mis problemas
00:02:18.300 --> 00:02:21.500
y apagando su ordena
00:02:21.500 --> 00:02:24.500
se acaban tos mis problemas
00:02:24.500 --> 00:02:27.200
Y yo la quiero...
00:02:30.000 --> 00:02:34.800
Como el sol a la mañana...
00:02:35.300 --> 00:02:38.300
Como los rayos de luz
00:02:38.300 --> 00:02:41.300
a mi ventana yo la quiero.
00:02:41.300 --> 00:02:44.200
Como los rayos de luz
00:02:44.200 --> 00:02:48.600
a mi ventana, ay chiquilla!

BIN
bideoak/chiquilla/cover.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
bideoak/chiquilla/thumb.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -0,0 +1,51 @@
[Script Info]
ScriptType: v4.00+
PlayResX: 1280
PlayResY: 720
WrapStyle: 0
ScaledBorderAndShadow: yes
Title: Default Aegisub file
YCbCr Matrix: TV.601
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default-furigana,Arial,10,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,1,1,2,10,10,10,1
Style: Default,Arial,40,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code once,function char_counter(ref) ci[ref] = ci[ref] + 1; return "" end
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code line all,ci = {0,0}; delay = 800; delay_2 = 300
Comment: 1,0:00:00.00,0:00:00.00,Default,,0,0,0,template char,!char_counter(1)!!retime("start2syl",-1500+(ci[1]-1)*50,0)!{\an8\alpha&HAF\fscx50\fscy50\bord1\3c&HFFFFFF&\1c&HFFFFFF&\blur1\t(!$scenter-$lleft+200!,!$scenter!,\fscx120\fscy120\alpha&0&)\pos($scenter,$smiddle)\fscx100\fscy100\shad0}
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl,!retime("syl",0,0)!{\an2\pos($center, !$smiddle - 5!)\fscx100\fscy100\c&HFFFFFF&\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\blur5\bord2\t(0,!$dur*0.5!,\frz!math.random(-30,30)!)\t(!$dur*0.5!,$dur,\frz0)\t(0,300,\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\c&HFFFFFF&\bord5\blur6)\t(300,$dur,\c\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\bord2\blur1)}
Dialogue: 0,0:00:20.30,0:00:22.50,Default,,0,0,0,karaoke,{\k30}Pa{\k23}ra {\k22}ins{\k15}ta{\k29}lar {\k34}la {\k31}Deb{\k36}ian
Dialogue: 0,0:00:23.50,0:00:25.40,Default,,0,0,0,karaoke,{\k17}Pa{\k26}ra {\k22}ins{\k15}ta{\k30}lar {\k26}la {\k27}Deb{\k27}ian
Dialogue: 0,0:00:25.40,0:00:29.36,Default,,0,0,0,karaoke,{\k42}Se ne{\k29}ce{\k17}si{\k56}ta {\k21}un {\k27}CD {\k57}o una {\k23}me{\k23}mo{\k101}ria
Dialogue: 0,0:00:29.40,0:00:31.80,Default,,0,0,0,karaoke,{\k71}Un {\k31}CD{\k12} o{\k17} u{\k21}na {\k25}me{\k30}mo{\k33}ria
Dialogue: 0,0:00:31.90,0:00:33.20,Default,,0,0,0,karaoke,{\k22}Si {\k22}la {\k29}red {\k21}no {\k36}tira
Dialogue: 0,0:00:33.30,0:00:34.50,Default,,0,0,0,karaoke,{\k21}Si {\k21}la {\k28}red {\k21}no {\k29}tira
Dialogue: 0,0:00:36.20,0:00:37.60,Default,,0,0,0,karaoke,{\k29}Que {\k30}tipo {\k21}de {\k18}me{\k13}mo{\k29}ria
Dialogue: 0,0:00:37.60,0:00:41.70,Default,,0,0,0,karaoke,{\k30}U{\k54}S{\k54}B {\k42}U{\k61}S{\k53}B {\k39}U{\k59}S{\k18}B
Dialogue: 0,0:00:42.20,0:00:44.20,Default,,0,0,0,karaoke,{\k18}Yo {\k23}no {\k28}soy {\k30}win{\k20}dow{\k24}se{\k57}ro
Dialogue: 0,0:00:44.90,0:00:46.80,Default,,0,0,0,karaoke,{\k33}yo {\k36}no {\k24}soy {\k21}win{\k19}dow{\k22}se{\k35}ro
Dialogue: 0,0:00:46.80,0:00:52.40,Default,,0,0,0,karaoke,{\k54}ni {\k38}uso {\k48}mac, {\k35}ni {\k71}uso {\k50}mac {\k42}ni {\k55}uso {\k197}mac
Dialogue: 0,0:00:52.40,0:00:55.20,Default,,0,0,0,karaoke,{\k49}Deb{\k66}ian {\k45}Deb{\k120}ian
Dialogue: 0,0:00:55.25,0:00:58.40,Default,,0,0,0,karaoke,{\k68}Deb{\k90}ian {\k45}Deb{\k112}ian
Dialogue: 0,0:00:58.45,0:01:02.90,Default,,0,0,0,karaoke,{\k59}Deb{\k79}ian {\k62}Deb{\k245}ian
Dialogue: 0,0:01:03.30,0:01:05.80,Default,,0,0,0,karaoke,{\k23}Pa{\k13}ra {\k16}ins{\k13}ta{\k28}lar {\k29}la {\k38}Deb{\k90}ian
Dialogue: 0,0:01:06.20,0:01:08.00,Default,,0,0,0,karaoke,{\k29}Pa{\k11}ra {\k10}ins{\k17}ta{\k29}lar {\k25}la {\k27}Deb{\k32}ian
Dialogue: 0,0:01:08.10,0:01:11.15,Default,,0,0,0,karaoke,{\k27}Se {\k15}ne{\k25}ce{\k20}si{\k16}ta {\k39}un {\k41}CD {\k10}o {\k7}u{\k31}na {\k21}me{\k23}mo{\k30}ria
Dialogue: 0,0:01:12.35,0:01:15.40,Default,,0,0,0,karaoke,{\k25}Un {\k29}CD {\k12}o {\k33}una {\k25}me{\k20}mo{\k21}ria {\k25}si {\k25}la {\k33}red {\k24}no {\k33}tira
Dialogue: 0,0:01:15.50,0:01:16.85,Default,,0,0,0,karaoke,{\k24}si {\k24}la {\k32}red {\k24}no {\k31}tira
Dialogue: 0,0:01:48.00,0:01:50.00,Default,,0,0,0,karaoke,{\k13}Pa{\k12}ra {\k21}ins{\k18}ta{\k24}lar {\k33}la {\k30}Deb{\k49}ian
Dialogue: 0,0:01:50.90,0:01:52.70,Default,,0,0,0,karaoke,{\k13}Pa{\k20}ra {\k18}ins{\k18}ta{\k22}lar {\k33}la {\k28}Deb{\k28}ian
Dialogue: 0,0:01:52.70,0:01:56.20,Default,,0,0,0,karaoke,{\k28}se {\k17}ne{\k30}ce{\k24}si{\k32}ta {\k19}un {\k35}CD {\k25}o {\k13}u{\k16}na {\k21}me{\k21}mo{\k69}ria
Dialogue: 0,0:01:56.80,0:01:58.65,Default,,0,0,0,karaoke,{\k29}un {\k37}CD {\k19}o {\k39}una {\k22}me{\k25}mo{\k14}ria
Dialogue: 0,0:01:58.65,0:02:00.00,Default,,0,0,0,karaoke,{\k24}si {\k24}la {\k32}red {\k24}no {\k31}tira
Dialogue: 0,0:02:00.00,0:02:01.60,Default,,0,0,0,karaoke,{\k28}si {\k28}la {\k38}red {\k28}no {\k38}tira
Dialogue: 0,0:02:03.00,0:02:04.50,Default,,0,0,0,karaoke,{\k26}Qué {\k32}ti{\k21}po {\k15}de {\k11}me{\k22}mo{\k23}ria
Dialogue: 0,0:02:04.50,0:02:09.20,Default,,0,0,0,karaoke,{\k38}U{\k38}S{\k76}B {\k52}U{\k40}S{\k57}B {\k48}U{\k38}S{\k83}B
Dialogue: 0,0:02:10.00,0:02:12.40,Default,,0,0,0,karaoke,{\k47}Deb{\k72}ian {\k56}Deb{\k65}ian
Dialogue: 0,0:02:13.00,0:02:15.00,Default,,0,0,0,karaoke,{\k66}Deb{\k62}ian {\k42}Deb{\k30}ian
Dialogue: 0,0:02:15.80,0:02:17.90,Default,,0,0,0,karaoke,{\k90}Deb{\k55}ian {\k38}Deb{\k27}ian

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
[Script Info]
ScriptType: v4.00+
PlayResX: 480
PlayResY: 360
WrapStyle: 0
ScaledBorderAndShadow: yes
Title: Default Aegisub file
YCbCr Matrix: TV.601
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,CyrBit,48,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code once,function char_counter(ref) ci[ref] = ci[ref] + 1; return "" end
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code line all,ci = {0,0}; delay = 800; delay_2 = 300
Comment: 1,0:00:00.00,0:00:00.00,Default,,0,0,0,template char,!char_counter(1)!!retime("start2syl",-1500+(ci[1]-1)*50,0)!{\an8\alpha&HAF\fscx50\fscy50\bord1\3c&HFFFFFF&\1c&HFFFFFF&\blur1\t(!$scenter-$lleft+200!,!$scenter!,\fscx120\fscy120\alpha&0&)\pos($scenter,$smiddle)\fscx100\fscy100\shad0}
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl,!retime("syl",0,0)!{\an2\pos($center, !$smiddle - 5!)\fscx100\fscy100\c&HFFFFFF&\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\blur5\bord2\t(0,!$dur*0.5!,\frz!math.random(-30,30)!)\t(!$dur*0.5!,$dur,\frz0)\t(0,300,\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\c&HFFFFFF&\bord5\blur6)\t(300,$dur,\c\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\bord2\blur1)}
Dialogue: 0,0:00:14.90,0:00:19.59,Default,,0,0,0,,{\k40}GNU {\k21}es {\k14}un {\k12}a{\k31}cro{\k14}ni{\k20}mo{\k50} {\k40}gnu {\k30}es{\k30}ta{\k17} {\k29}com{\k42}pues{\k79}to
Dialogue: 0,0:00:21.50,0:00:27.09,Default,,0,0,0,,{\k14}tie{\k15}ne {\k9}to{\k21}do{\k15} i{\k15}ni{\k32}cia{\k27}les {\k40}es {\k32}un {\k39}nombre {\k26}cor{\k38}to {\k22}y {\k45}re{\k43}cur{\k41}si{\k85}vo
Dialogue: 0,0:00:28.00,0:00:31.50,Default,,0,0,0,,{\k31}li{\k15}nux {\k23}no {\k20}pue{\k15}de {\k41}ser {\k66}eso {\k6}no {\k19}hay {\k21}quien {\k8}lo {\k8}a{\k30}guan{\k47}te
Dialogue: 0,0:00:31.50,0:00:34.69,Default,,0,0,0,,{\k28}tie{\k19}ne {\k14}que {\k12}lle{\k82}var {\k18}el {\k46}gnu {\k19}por {\k11}de{\k28}lan{\k42}te
Dialogue: 0,0:00:34.80,0:00:37.79,Default,,0,0,0,,{\k38}bill {\k22}es{\k16}ta {\k19}fu{\k20}rio{\k39}so {\k40}bill {\k19}no {\k24}esta {\k13}con{\k26}ten{\k23}to
Dialogue: 0,0:00:37.90,0:00:41.20,Default,,0,0,0,,{\k47}al{\k24}guien {\k11}va {\k6}a {\k16}tum{\k48}bar {\k43}su im{\k34}pe{\k101}rio
Dialogue: 0,0:00:41.41,0:00:44.51,Default,,0,0,0,,{\k18}se {\k42}monta {\k17}una {\k66}charla,{\k24} {\k27}stall{\k20}man {\k13}an{\k15}da {\k40}suel{\k28}to
Dialogue: 0,0:00:44.52,0:00:47.90,Default,,0,0,0,,{\k23}va{\k14} a {\k12}em{\k18}pe{\k18}zar {\k27}la {\k34}char{\k34}la, {\k57}co{\k101}rre!
Dialogue: 0,0:01:20.50,0:01:24.00,Default,,0,0,0,,{\k55}en {\k36}su {\k28}re{\k18}po {\k42}hay {\k60}par{\k23}ches {\k21}de {\k16}la {\k20}pe{\k51}ña
Dialogue: 0,0:01:24.20,0:01:25.70,Default,,0,0,0,,{\k34}Bill {\k17}no {\k12}fli{\k28}pes {\k26}tan{\k33}to
Dialogue: 0,0:01:25.80,0:01:27.20,Default,,0,0,0,,{\k19}va{\k38}mos {\k21}a {\k14}tum{\k18}bar{\k30}lo

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,143 +1,21 @@
import json
import os
from shutil import copytree, copy
from pathlib import Path, PurePath
from shutil import copy
from pathlib import Path
import subprocess
from jinja2 import Template, Environment, PackageLoader, select_autoescape
from jinja2 import Environment, PackageLoader, select_autoescape
from jinja2.utils import Markup
import asstosrt
import srt
import webvtt
class SongPage:
THUMBNAIL_GEOMETRY = '200x200'
def __init__(self, path, root):
self.name = path.name
self.original = None
self.author = None
self.path = path
self.root = root
self.video = None
self.video_type = None
self.vtt = None
self.srt = None
self.ass = None
self.cover = None
self.thumbnail = None
self.files = []
self.search_media()
def search_media(self):
for entry in self.path.iterdir():
if entry.name == 'metadata.json':
with entry.open('r') as metadatafile:
self.metadata = json.load(metadatafile)
if 'name' in self.metadata:
self.name = self.metadata['name']
if 'original' in self.metadata:
self.original = self.metadata['original']
if 'author' in self.metadata:
self.author = self.metadata['author']
elif entry.name.endswith('mp4'):
self.video = entry
self.video_type = 'video/mp4'
self.files.append(entry)
elif entry.name.endswith('webm'):
self.video = entry
self.video_type = 'video/webm'
self.files.append(entry)
elif entry.name.endswith('ogv'):
self.video = entry
self.video_type = 'video/ogg'
self.files.append(entry)
elif entry.name.endswith('vtt'):
self.vtt = entry
elif entry.name == "{}.srt".format(self.path.name):
self.srt = entry
self.files.append(entry)
elif entry.name.endswith('ass'):
self.ass = entry
self.files.append(entry)
elif entry.name == 'thumb.jpg':
self.thumbnail = entry
elif entry.name == 'cover.jpg':
self.cover = entry
elif entry.name == 'index.html':
continue
else:
self.files.append(entry)
if self.srt is None and self.ass is not None:
self.srt = self.path / "{}.srt".format(self.path.name)
with self.ass.open('r') as assfile, self.srt.open('w') as srtfile:
srtfile.write(asstosrt.convert(assfile))
self.files.append(self.srt)
if self.vtt is None and self.srt is not None:
srtfile = self.path / self.srt
self.vtt = self.path / "{}.vtt".format(self.path.name)
webvtt.from_srt(str(self.srt.absolute())).save(str(self.vtt.absolute()))
if self.cover is None and self.video is not None:
self.cover = self.path / "cover.jpg"
command = [
'ffmpeg',
'-loglevel', 'quiet',
'-i', str(self.video.absolute()),
'-vcodec', 'mjpeg',
'-vframes', '1',
'-an',
'-f', 'rawvideo',
'-ss', '2',
str(self.cover.absolute()),
]
subprocess.check_call(command)
if self.thumbnail is None and self.cover is not None:
self.thumbnail = self.path / "thumb.jpg"
subprocess.check_call([
'convert',
str(self.cover.absolute()),
'-resize', self.THUMBNAIL_GEOMETRY,
str(self.thumbnail.absolute()),
])
@property
def publish(self):
has_subtitles = self.ass or self.srt or self.vtt
has_video = self.video
return has_video and has_subtitles
def get_context_data(self):
parsed_srt = None
if self.srt:
with self.srt.open('r') as srtfile:
try:
srt_str = srtfile.read().encode('utf-8').decode('utf-8-sig')
parsed_srt = list(srt.parse(srt_str))
except Exception as e:
print("{}: srt parse error: {}".format(self.path.name, e))
root_path = os.path.relpath(self.root, self.path)
return {
'song': self,
'parsed_srt': parsed_srt,
'root_path': root_path,
}
def render(self, builder, context):
ctx = self.get_context_data()
ctx.update(context)
builder.render('song.html', self.path, ctx)
from .songs import load_songs
from .karaoke_templates import update_karaoke_songs
class Builder:
def __init__(self, root_folder, libreto):
self.root_folder = root_folder
self.libreto = libreto
self.static_dir = Path(__file__).parent / 'static'
self.src_dir = Path(__file__).parent
self.static_dir = self.src_dir / 'static'
self.env = Environment(
loader=PackageLoader('negromateweb', 'templates'),
@ -166,25 +44,7 @@ class Builder:
page.write(page_template.render(context))
def build(self):
songs = []
pending_songs = []
for entry in self.root_folder.iterdir():
if entry.name in ['static', 'playlist', 'home', 'todo']:
continue
if entry.is_dir():
print("building {}".format(entry.name))
try:
songpage = SongPage(entry, self.root_folder)
except Exception as e:
raise e
print("Error: {}".format(e))
continue
if songpage.publish:
songs.append(songpage)
else:
pending_songs.append(songpage)
songs.sort(key=lambda a: a.name)
songs, pending_songs = load_songs(self.root_folder)
global_context = {
'songs': songs,
'root_folder': self.root_folder,
@ -219,6 +79,9 @@ class Builder:
todo_context.update(global_context)
self.render('todo.html', todo, todo_context)
template_file = self.src_dir / 'templates' / 'karaoke.ass'
update_karaoke_songs(songs, template_file)
static = self.root_folder / 'static'
if not static.exists():

View File

@ -0,0 +1,89 @@
import os
import subprocess
import time
from contextlib import contextmanager
import ass
from .utils import needs_change
@contextmanager
def Xephyr_env(display=":2", *args, **kwargs):
env = os.environ.copy()
xephyr = subprocess.Popen(["Xephyr", display])
env['DISPLAY'] = display
try:
yield env
finally:
xephyr.kill()
def set_template(template_subtitles, orig_file, target_file=None):
if target_file is None:
target_file = orig_file
with open(orig_file, 'r') as orig:
subtitles = ass.parse(orig)
new_events = []
for dialogue in template_subtitles.events:
new_events.append(dialogue)
for dialogue in subtitles.events:
if dialogue.effect.startswith('code'):
continue
if dialogue.effect.startswith('template'):
continue
new_events.append(dialogue)
subtitles.events = new_events
with open(target_file, 'w', encoding='utf-8-sig') as target:
subtitles.dump_file(target)
def run(command, env, wait=None):
program = subprocess.Popen(
command,
env=env,
)
if wait is not None:
time.sleep(wait)
def apply_template(subtitles, env):
run(["aegisub-3.2", subtitles], env=env, wait=2)
# Si pide confirmación para cargar video ignorar el popup
run(["xdotool", "key", "Escape"], env=env, wait=0.1)
# abrir el menú de automatización, bajar dos y darle a aplicar template
run(["xdotool", "key", "alt+u"], env=env, wait=0.1)
run(["xdotool", "key", "Down"], env=env, wait=0.1)
run(["xdotool", "key", "Down"], env=env, wait=0.1)
run(["xdotool", "key", "Return"], env=env, wait=2)
# guardar
run(["xdotool", "key", "ctrl+s"], env=env)
# cerrar programa
run(["xdotool", "key", "ctrl+q"], env=env)
def update_karaoke_songs(songs, template_file):
with open(template_file, 'r') as template:
template_subtitles = ass.parse(template)
with Xephyr_env() as env:
for song in songs:
if song.metadata.get('karaoke'):
target = song.path / "{}.karaoke.ass".format(song.path.name)
if needs_change(target, (song.ass, template_file)):
set_template(
template_subtitles=template_subtitles,
orig_file=str(song.ass),
target_file=str(target)
)
time.sleep(2)
apply_template(str(target), env)
time.sleep(2)

164
web/negromateweb/songs.py Normal file
View File

@ -0,0 +1,164 @@
import json
import os
import subprocess
import asstosrt
import srt
import webvtt
from .utils import needs_change
class SongPage:
THUMBNAIL_GEOMETRY = '200x200'
def __init__(self, path, root):
self.name = path.name
self.metadata = None
self.original = None
self.author = None
self.path = path
self.root = root
self.video = None
self.video_type = None
self.vtt = None
self.srt = None
self.karaoke_ass = None
self.ass = None
self.cover = None
self.thumbnail = None
self.files = []
self.search_media()
def search_media(self):
for entry in self.path.iterdir():
if entry.name == 'metadata.json':
with entry.open('r') as metadatafile:
self.metadata = json.load(metadatafile)
if 'name' in self.metadata:
self.name = self.metadata['name']
if 'original' in self.metadata:
self.original = self.metadata['original']
if 'author' in self.metadata:
self.author = self.metadata['author']
elif entry.name.endswith('mp4'):
self.video = entry
self.video_type = 'video/mp4'
self.files.append(entry)
elif entry.name.endswith('webm'):
self.video = entry
self.video_type = 'video/webm'
self.files.append(entry)
elif entry.name.endswith('ogv'):
self.video = entry
self.video_type = 'video/ogg'
self.files.append(entry)
elif entry.name.endswith('vtt'):
self.vtt = entry
elif entry.name == "{}.srt".format(self.path.name):
self.srt = entry
self.files.append(entry)
elif entry.name == "{}.karaoke.ass".format(self.path.name):
self.karaoke_ass = entry
self.files.append(entry)
elif entry.name == "{}.ass".format(self.path.name):
self.ass = entry
self.files.append(entry)
elif entry.name == 'thumb.jpg':
self.thumbnail = entry
elif entry.name == 'cover.jpg':
self.cover = entry
elif entry.name == 'index.html':
continue
else:
self.files.append(entry)
srt = self.path / "{}.srt".format(self.path.name)
if needs_change(srt, (self.ass,)):
self.srt = srt
with self.ass.open('r') as assfile, self.srt.open('w') as srtfile:
srtfile.write(asstosrt.convert(assfile))
self.files.append(self.srt)
vtt = self.path / "{}.vtt".format(self.path.name)
if needs_change(vtt, (self.srt,)):
self.vtt = vtt
webvtt.from_srt(str(self.srt.absolute())).save(str(self.vtt.absolute()))
cover = self.path / "cover.jpg"
if needs_change(cover, (self.video,)):
self.cover = cover
command = [
'ffmpeg',
'-loglevel', 'quiet',
'-i', str(self.video.absolute()),
'-vcodec', 'mjpeg',
'-vframes', '1',
'-an',
'-f', 'rawvideo',
'-ss', '2',
'-y',
str(self.cover.absolute()),
]
subprocess.check_call(command)
thumbnail = self.path / "thumb.jpg"
if needs_change(thumbnail, (self.cover,)):
self.thumbnail = thumbnail
subprocess.check_call([
'convert',
str(self.cover.absolute()),
'-resize', self.THUMBNAIL_GEOMETRY,
str(self.thumbnail.absolute()),
])
@property
def publish(self):
has_subtitles = self.ass or self.srt or self.vtt
has_video = self.video
return has_video and has_subtitles
def get_context_data(self):
parsed_srt = None
if self.srt:
with self.srt.open('r') as srtfile:
try:
srt_str = srtfile.read().encode('utf-8').decode('utf-8-sig')
parsed_srt = list(srt.parse(srt_str))
except Exception as e:
print("{}: srt parse error: {}".format(self.path.name, e))
root_path = os.path.relpath(self.root, self.path)
return {
'song': self,
'parsed_srt': parsed_srt,
'root_path': root_path,
}
def render(self, builder, context):
ctx = self.get_context_data()
ctx.update(context)
builder.render('song.html', self.path, ctx)
def load_songs(root_folder):
songs = []
pending_songs = []
for entry in root_folder.iterdir():
if entry.name in ['static', 'playlist', 'home', 'todo']:
continue
if entry.is_dir():
print("building {}".format(entry.name))
try:
songpage = SongPage(entry, root_folder)
except Exception as e:
raise e
print("Error: {}".format(e))
continue
if songpage.publish:
songs.append(songpage)
else:
pending_songs.append(songpage)
songs.sort(key=lambda a: a.name)
return songs, pending_songs

View File

@ -0,0 +1,9 @@
[Script Info]
Title: Template negro mate
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code once,function char_counter(ref) ci[ref] = ci[ref] + 1; return "" end
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code line all,ci = {0,0}; delay = 800; delay_2 = 300
Comment: 1,0:00:00.00,0:00:00.00,Default,,0,0,0,template char,!char_counter(1)!!retime("start2syl",-1500+(ci[1]-1)*50,0)!{\an8\alpha&HAF\fscx50\fscy50\bord1\3c&HFFFFFF&\1c&HFFFFFF&\blur1\t(!$scenter-$lleft+200!,!$scenter!,\fscx120\fscy120\alpha&0&)\pos($scenter,$smiddle)\fscx100\fscy100\shad0}
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl,!retime("syl",0,0)!{\an2\pos($center, !$smiddle - 5!)\fscx100\fscy100\c&HFFFFFF&\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\blur5\bord2\t(0,!$dur*0.5!,\frz!math.random(-30,30)!)\t(!$dur*0.5!,$dur,\frz0)\t(0,300,\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\c&HFFFFFF&\bord5\blur6)\t(300,$dur,\c\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\3c!_G.ass_color(_G.HSV_to_RGB(360*(syl.i/$syln)*$kdur,1,1))!\bord2\blur1)}

14
web/negromateweb/utils.py Normal file
View File

@ -0,0 +1,14 @@
def needs_change(destination, dependencies):
last_dependency_change = 0
for dependency in dependencies:
if dependency is None:
return False
last_dependency_change = max(
last_dependency_change,
dependency.lstat().st_mtime
)
if not destination.exists():
return True
return destination.lstat().st_mtime < last_dependency_change