Added colors from clipboard-choice
This commit is contained in:
parent
8246d61a1b
commit
4774927c52
273
app.py
273
app.py
@ -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",
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user