Added colors from clipboard-choice

This commit is contained in:
Lasse Studion 2023-03-14 13:27:51 +01:00
parent 8246d61a1b
commit 4774927c52

273
app.py
View File

@ -6,7 +6,7 @@ from bs4 import BeautifulSoup
def find_start_seconds(region):
''' Returns start second for region. '''
"""Returns start second for region."""
if len(region["Start"]) > 9:
start_time = datetime.strptime(region["Start"], "%H:%M:%S.%f")
elif len(region["Start"]) in [8, 9]:
@ -17,8 +17,9 @@ def find_start_seconds(region):
t = start_time.time()
return (t.hour * 60 + t.minute) * 60 + t.second
def find_lenght_seconds(region):
''' Returns lenght of region in seconds. '''
"""Returns lenght of region in seconds."""
if len(region["Length"]) > 9:
lenght = datetime.strptime(region["Length"], "%H:%M:%S.%f")
elif len(region["Length"]) in [8, 9]:
@ -28,26 +29,46 @@ def find_lenght_seconds(region):
t = lenght.time()
return (t.hour * 60 + t.minute) * 60 + t.second
def colorize(soup):
# Get colors from clips on timeline.
colors = {}
n_regions = len(timline.find_all("Region"))
for region in timline.find_all("Region"):
timeline = soup.find("Tracks")
for region in timeline.find_all("Region"):
try:
colors[str(region["Ref"])] = int(region["Colour"])
except:
pass
# Give colors to clips in clipboard
for group in soup.find_all("Group"):
soup = colorize_clipboard(soup, colors)
soup = colorize_timeline(soup, colors)
return soup
def colorize_clipboard(soup, colors):
"""Give colors to clips in clipboard."""
clipboard = soup.find("Clipboard")
for group in clipboard.find_all("Group"):
# new_group_tag = soup.new_tag('Group', {'Caption':group['Caption'], 'IsExpanded':group['IsExpanded']})
new_group_tag = group
# Go over clips (nested regions).
for clip in group.find_all("Clip"):
# new_clip_tag = soup.new_tag('Clip', {'Name':clip['Name'], 'Start':clip['Start'], 'Length':clip['Length']})
new_clip_tag = clip
for region in clip.find_all("Region"):
new_region_tag = region
try:
new_region_tag["Colour"] = colors[region["Ref"]]
except KeyError:
new_region_tag["Colour"] = "0"
new_clip_tag.append(new_region_tag)
new_group_tag.append(new_clip_tag)
# Go over regions.
for region in group.find_all("Region"):
try:
with s:
st.markdown(f':green[{region["Name"]}]')
sleep(1/(n_regions))
except KeyError:
pass
if region.parent.name == "Clip":
continue
new_region_tag = region
try:
new_region_tag["Colour"] = colors[region["Ref"]]
@ -58,38 +79,82 @@ def colorize(soup):
soup.Session.Clipboard.replace_with(new_clipboard_tag)
return soup
def colorize_timeline(soup, colors):
print(colors)
# Give colors to clips on timeline.
new_tracks_tag = soup.find("Tracks")
tracks = soup.find("Tracks")
for track in tracks.find_all("Track"):
try:
with s:
st.markdown(f':green[{region["Name"]}]')
sleep(1/(n_regions))
except KeyError:
pass
new_track_tag = track
for region in track.find_all("Region"):
new_region_tag = region
try:
new_region_tag["Colour"] = colors[region["Ref"]]
except KeyError:
print(region)
new_region_tag["Colour"] = "0"
new_track_tag.append(new_region_tag)
new_tracks_tag.append(new_track_tag)
soup.Session.Tracks.replace_with(new_tracks_tag)
return soup
def print_analyzing(soup):
regions = soup.find_all("Region")
n_regions = len(regions)
for region in regions:
try:
with s0:
st.markdown(f':green[{region["Name"]}]')
sleep(1 / (n_regions * 2))
except KeyError:
pass
def colorize_groups(soup):
"""Give color to regions based on groups they are in."""
groups = soup.find_all("Group")
ids = []
ids_groups = []
for group in reversed(groups):
print(group["Caption"])
regions = []
# try:
for region in group.find_all("Region"):
if region["Ref"] not in ids: # Exclude if already in another group.
regions.append(region["Ref"])
# except:
# pass
ids += regions
ids_groups.append(regions)
colors = {}
for group in ids_groups:
group_color = (ids_groups.index(group) * 50) % 360
for ref in group:
colors[ref] = group_color
soup = colorize_clipboard(soup, colors)
soup = colorize_timeline(soup, colors)
return soup
def make_rainbow(soup):
''' Returns a tracks tag colored like a rainbow. '''
"""Returns a tracks tag colored like a rainbow."""
new_tracks_tag = soup.find("Tracks")
tracks = soup.find("Tracks")
regions = tracks.find_all("Region")
min_start = min([find_start_seconds(i) for i in regions])
max_end = max([int(find_start_seconds(i) + find_lenght_seconds(i)) for i in regions])
max_end = max(
[int(find_start_seconds(i) + find_lenght_seconds(i)) for i in regions]
)
lenght = int(max_end-min_start)
lenght = int(max_end - min_start)
# Give colors to clips on timeline.
new_tracks_tag = soup.find("Tracks")
@ -99,102 +164,136 @@ def make_rainbow(soup):
for region in track.find_all("Region"):
new_region_tag = region
try:
middle = find_start_seconds(region) + find_lenght_seconds(region)/2
new_region_tag["Colour"] = int(((middle)/lenght)*360)
middle = find_start_seconds(region) + find_lenght_seconds(region) / 2
new_region_tag["Colour"] = int(((middle) / lenght) * 360)
except KeyError:
new_region_tag["Colour"] = "0"
new_track_tag.append(new_region_tag)
new_tracks_tag.append(new_track_tag)
return new_tracks_tag
print_sleep = False
soup.Session.Tracks.replace_with(new_tracks_tag)
return soup
st.title(":green[Colorize] your :red[Hindenburg] project")
st.markdown(
t1, t2, t3 = st.tabs(['From timeline', 'From clipboard', 'As rainbow 🌈'])
with t1:
st.markdown(
"""
1. Set colors for a few clips on your timeline, ideally at least one clip from
each recording.
2. Upload your Hindenburg project file (ending with *.nhsx*) below to add the same color
to other clips originating from the same recording.
3. Choose *Colors from timeline* to download the project file **and put it in the same folder as your original project file**.
"""
1. Set colors for a few clips on your timeline, ideally at least one clip from
each recording.
2. Upload your Hindenburg project file (ending with *.nhsx*) below to add the same color
to other clips originating from the same recording.
3. Download the modified file *and put it in the same folder as your original project file*.
**No data is saved anywhere**. Made by [Lasse Edfast](https://lasseedfast.se). You need to be using Hindenburg 2.0 to use colors.
"""
)
)
with st.expander(label='Unclear? See an example here.', expanded=False):
st.write('*Put colors on clips like this...*')
st.image('before.png')
st.write('*...and you get a file that looks like this*')
st.image('after.png')
with st.expander(label="Unclear? See an example here.", expanded=False):
st.write("*Put colors on clips like this...*")
st.image("before.png")
st.write("*...and you get a file that looks like this*")
st.image("after.png")
with t2:
st.markdown('''
This alternative can be good if you have created clipboards for each person/interview as all clips in the same clipboard will
be given the same color.
If you have clips originating from the same recording in different clipboards it will be given the
color for the last clipbord where it is included.
Choose *Colors from clipboard* to download the project file **and put it in the same folder as your original project file**.
''')
with t3:
st.markdown('''
This alternative makes your timeline into a beautiful rainbow! Lots of love but maybe not where you will start a longer project.
Choose *Download rainbow project!* to download the project file **and put it in the same folder as your original project file**.
''')
st.markdown('No data is saved anywhere. Made by [Lasse Edfast](https://lasseedfast.se). You need to be using Hindenburg 2.0 to use colors.')
# Ask for file.
uploaded_file = st.file_uploader(
"*Upload your project file*", label_visibility="hidden", type="nhsx", accept_multiple_files=False
"*Upload your project file*",
label_visibility="hidden",
type="nhsx",
accept_multiple_files=False,
)
if uploaded_file:
# Make soup.
stringio = StringIO(uploaded_file.getvalue().decode("utf-8"))
soup = BeautifulSoup(stringio.read(), "xml")
if "soup" not in st.session_state: # Make soup.
stringio = StringIO(uploaded_file.getvalue().decode("utf-8"))
soup = BeautifulSoup(stringio.read(), "xml")
st.session_state["soup"] = soup
soup = st.session_state["soup"]
project_name = soup.find("AudioPool")["Path"].replace(" Files", "")
new_clipboard_tag = soup.new_tag("Clipboard")
timline = soup.find("Tracks")
s0 = st.empty()
with s0:
if 'analyzed' not in st.session_state:
print_analyzing(soup)
sleep(1)
st.session_state['analyzed'] = True
st.markdown("Choose your colors:")
sleep(0.3)
# Area to print things.
c1, c2 = st.columns(2)
with c1:
s = st.empty()
c1, c2, c3 = st.columns(3)
if 'soup' not in st.session_state:
soup = colorize(soup)
st.session_state['soup'] = soup
print_sleep = True # Sleep while with print if first run.
else:
soup = st.session_state['soup']
# Allow the user to download file.
with c1:
with s:
if print_sleep:
st.markdown(":green[Exporting...]")
sleep(0.7)
st.download_button(
"🎈 Download file",
soup.encode("utf-8"),
file_name=f"{project_name}_colors.nhsx",
)
if "soup1" not in st.session_state:
soup1 = colorize(soup)
st.session_state["soup1"] = soup1
soup1 = st.session_state["soup1"]
# Allow the user to download file.
st.download_button(
"🎨 Colors from timeline",
soup1.encode("utf-8"),
file_name=f"{project_name}_colors.nhsx",
)
with c2:
e = st.empty()
with e:
rainbow = st.button('🌈 Turn timeline into a rainbow! 🌈')
if "soup2" not in st.session_state:
soup2 = colorize_groups(soup)
st.session_state["soup2"] = soup2
soup2 = st.session_state["soup2"]
st.download_button(
"🎨 Colors from clipboard",
soup2.encode("utf-8"),
file_name=f"{project_name}_colors.nhsx",
)
with c3:
if "soup3" not in st.session_state:
soup3 = make_rainbow(soup)
st.session_state["soup3"] = soup3
else:
soup3 = st.session_state["soup3"]
s3 = st.empty()
with s3:
rainbow = st.button("🌈 Rainbow timeline!")
if rainbow:
for _ in range(0, 4):
with e:
st.markdown('🌧️')
with s3:
st.markdown("🌧️")
sleep(0.4)
with e:
st.markdown('')
with s3:
st.markdown("")
sleep(0.15)
with e:
st.markdown('🌦️')
with s3:
st.markdown("🌦️")
sleep(1)
with e:
with s3:
rainbows = []
for _ in range(0,10):
rainbows.append('🌈')
st.markdown(''.join(rainbows))
for _ in range(0, 10):
rainbows.append("🌈")
st.markdown("".join(rainbows))
sleep(0.09)
new_tracks_tag = make_rainbow(soup)
soup.Session.Tracks.replace_with(new_tracks_tag)
with e:
with s3:
st.download_button(
"🌈 Download rainbow project",
soup.encode("utf-8"),
file_name=f"{project_name}_rainbow.nhsx",
)
"🌈 Download rainbow project! 🌈",
soup3.encode("utf-8"),
file_name=f"{project_name}_rainbow.nhsx",
)