Compare commits
1 Commits
master
...
422aefd3e0
| Author | SHA1 | Date | |
|---|---|---|---|
| 422aefd3e0 |
5
btfs.sh
5
btfs.sh
@@ -36,9 +36,8 @@ movie=$(echo $movie|xargs)
|
|||||||
|
|
||||||
printf "Playing: %s\n" "$movie"
|
printf "Playing: %s\n" "$movie"
|
||||||
#smplayer -fullscreen "$movie" 1>/dev/null
|
#smplayer -fullscreen "$movie" 1>/dev/null
|
||||||
mpv --fs --volume=100 "$movie" # 1>/dev/null
|
#mpv --fs --volume=100 "$movie" # 1>/dev/null
|
||||||
#vlc "$movie" 1>/dev/null
|
vlc "$movie" 1>/dev/null
|
||||||
#kodi "$movie" 1>/dev/null
|
|
||||||
printf "Unmounting: %s\n" "$mountpoint"
|
printf "Unmounting: %s\n" "$mountpoint"
|
||||||
fusermount -u "$mountpoint"
|
fusermount -u "$mountpoint"
|
||||||
printf "Removing dir: %s\n" "$mountpoint"
|
printf "Removing dir: %s\n" "$mountpoint"
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class MyHTMLParser(HTMLParser):
|
|||||||
self.a_href = False
|
self.a_href = False
|
||||||
def handle_data(self, data):
|
def handle_data(self, data):
|
||||||
if self.tbody and self.div and self.a_href:
|
if self.tbody and self.div and self.a_href:
|
||||||
print(' \t| '.join(self.timestamps) + '\t| ' + self.get_category() + '| ' + data.strip())
|
print('\t| '.join(self.timestamps) + '\t| ' + self.get_category() + '| ' + data.strip())
|
||||||
self.a_href = False
|
self.a_href = False
|
||||||
self.timestamps = []
|
self.timestamps = []
|
||||||
elif self.timestamp:
|
elif self.timestamp:
|
||||||
|
|||||||
19
checkpatch_project.sh
Executable file
19
checkpatch_project.sh
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#checkpatch --no-tree -f
|
||||||
|
checkpatch="/usr/lib/modules/$(uname -r)/build/scripts/checkpatch.pl"
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
project_dir="$PWD"
|
||||||
|
elif [ -d "$1" ]; then
|
||||||
|
project_dir="$1"
|
||||||
|
else
|
||||||
|
source_file="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$project_dir" ]; then
|
||||||
|
"${checkpatch}" --no-tree -f "${source_file}"
|
||||||
|
else
|
||||||
|
find "${project_dir}" -regex '.*\.\(c\|h\)' -exec "${checkpatch}" --no-tree -f '{}' +
|
||||||
|
fi
|
||||||
|
|
||||||
21
ffmpeg/ultrafast_x264_mp4.sh
Executable file
21
ffmpeg/ultrafast_x264_mp4.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Capture screen script
|
||||||
|
prefix=`date +"%G.%m.%d_%H.%M.%S"`
|
||||||
|
|
||||||
|
ffmpeg -y -f x11grab \
|
||||||
|
-video_size 1920x1080 \
|
||||||
|
-r 30 \
|
||||||
|
-i $DISPLAY \
|
||||||
|
-f pulse \
|
||||||
|
-ac 2 \
|
||||||
|
-i default \
|
||||||
|
-c:v libx264 \
|
||||||
|
-crf 0 \
|
||||||
|
-pix_fmt yuv420p \
|
||||||
|
-preset ultrafast \
|
||||||
|
-threads 0 \
|
||||||
|
$prefix.mp4
|
||||||
|
# -f alsa \
|
||||||
|
# -i hw:2,1 \
|
||||||
|
#-an \
|
||||||
@@ -55,7 +55,6 @@ class MovieList:
|
|||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -71,16 +70,14 @@ class MovieList:
|
|||||||
|
|
||||||
.dataTables_wrapper {
|
.dataTables_wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: auto;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_filter {
|
.dataTables_filter {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_filter label {
|
.dataTables_filter label {
|
||||||
@@ -116,19 +113,22 @@ class MovieList:
|
|||||||
padding: 0.5rem 0;
|
padding: 0.5rem 0;
|
||||||
color: rgba(255, 255, 255, 0.6);
|
color: rgba(255, 255, 255, 0.6);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_scroll {
|
.dataTables_scroll {
|
||||||
display: none;
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_scrollHead {
|
.dataTables_scrollHead {
|
||||||
display: none;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_scrollBody {
|
.dataTables_scrollBody {
|
||||||
display: none;
|
flex: 1;
|
||||||
|
overflow-y: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_scrollBody::-webkit-scrollbar {
|
.dataTables_scrollBody::-webkit-scrollbar {
|
||||||
@@ -144,20 +144,7 @@ class MovieList:
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_wrapper::-webkit-scrollbar {
|
table.dataTable.stripe tbody tr.odd,
|
||||||
width: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataTables_wrapper::-webkit-scrollbar-track {
|
|
||||||
background: rgba(255, 255, 255, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataTables_wrapper::-webkit-scrollbar-thumb {
|
|
||||||
background: rgba(255, 255, 255, 0.2);
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.dataTable.stripe tbody tr.odd,
|
|
||||||
table.dataTable.display tbody tr.odd,
|
table.dataTable.display tbody tr.odd,
|
||||||
table.dataTable tbody tr {
|
table.dataTable tbody tr {
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
@@ -287,23 +274,21 @@ class MovieList:
|
|||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
try {
|
$('#sortable').DataTable({
|
||||||
$('#sortable').DataTable({
|
"paging": false,
|
||||||
"paging": false,
|
"info": true,
|
||||||
"info": true,
|
"searching": true,
|
||||||
"searching": true,
|
"ordering": true,
|
||||||
"ordering": true,
|
"order": [[0, "asc"]],
|
||||||
"order": [[0, "desc"]],
|
"scrollY": "calc(100vh - 200px)",
|
||||||
"language": {
|
"scrollCollapse": true,
|
||||||
"search": "Search:",
|
"language": {
|
||||||
"info": "Showing _TOTAL_ movies",
|
"search": "Search:",
|
||||||
"infoEmpty": "No movies",
|
"info": "Showing _TOTAL_ movies",
|
||||||
"infoFiltered": "(filtered from _MAX_)"
|
"infoEmpty": "No movies",
|
||||||
}
|
"infoFiltered": "(filtered from _MAX_)"
|
||||||
});
|
}
|
||||||
} catch(e) {
|
});
|
||||||
console.error("DataTables init error:", e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
@@ -390,7 +375,7 @@ class MovieList:
|
|||||||
|
|
||||||
html_title_td = movie['title'] if 'dummy' in movie.keys() else \
|
html_title_td = movie['title'] if 'dummy' in movie.keys() else \
|
||||||
f'<a href="https://www.imdb.com/title/tt{movie.movieID}" target="_blank">{movie["title"]}</a>'
|
f'<a href="https://www.imdb.com/title/tt{movie.movieID}" target="_blank">{movie["title"]}</a>'
|
||||||
|
|
||||||
self.html_table[index] = (
|
self.html_table[index] = (
|
||||||
f'\n <tr>'
|
f'\n <tr>'
|
||||||
f'<td data-label="#">{index + 1}</td>'
|
f'<td data-label="#">{index + 1}</td>'
|
||||||
@@ -413,42 +398,29 @@ class MovieList:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
self.movie_list = {}
|
self.movie_list = {}
|
||||||
seen_titles = set() # Track unique titles
|
|
||||||
|
|
||||||
# Open the movie list & split the columns
|
# Open the movie list & split the columns
|
||||||
with open(self.src, 'r', encoding='utf-8') as fp_handle:
|
with open(self.src, 'r', encoding='utf-8') as fp_handle:
|
||||||
mlist_raw = fp_handle.read()
|
mlist_raw = fp_handle.read()
|
||||||
idx = 0
|
|
||||||
for raw_line in mlist_raw.splitlines():
|
for raw_line in mlist_raw.splitlines():
|
||||||
# In case the line is empty
|
# In case the line is empty
|
||||||
if not raw_line:
|
if not raw_line:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
title = raw_line[0:next((i for i, ch in enumerate(raw_line) if ch in {'<', '('}), None) - 1]
|
|
||||||
|
|
||||||
# Skip if we've already seen this title
|
|
||||||
if title in seen_titles:
|
|
||||||
continue
|
|
||||||
|
|
||||||
seen_titles.add(title)
|
|
||||||
self.movie_list.update({
|
self.movie_list.update({
|
||||||
idx: {
|
len(self.movie_list): {
|
||||||
'title': title,
|
'title': raw_line[0:next((i for i, ch in enumerate(raw_line) if ch in {'<', '('}), None) - 1],
|
||||||
'kind': raw_line[raw_line.find('<')+1:raw_line.rfind('>')+1].strip('<>') or 'movie',
|
'kind': raw_line[raw_line.find('<')+1:raw_line.rfind('>')+1].strip('<>') or 'movie',
|
||||||
'year': raw_line[raw_line.find('(')+1:raw_line.find(')')],
|
'year': raw_line[raw_line.find('(')+1:raw_line.find(')')],
|
||||||
'status': raw_line[raw_line.find('[')+1:raw_line.find(']')],
|
'status': raw_line[raw_line.find('[')+1:raw_line.find(']')],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
idx += 1
|
|
||||||
|
|
||||||
self.html_table = [None] * len(self.movie_list)
|
self.html_table = [None] * len(self.movie_list)
|
||||||
|
|
||||||
# Progress bar
|
# Progress bar
|
||||||
pbar = progressbar.ProgressBar(max_value=len(self.movie_list))
|
pbar = progressbar.ProgressBar(max_value=len(self.movie_list))
|
||||||
for idx, movie in self.movie_list.items():
|
for idx, movie in self.movie_list.items():
|
||||||
# More precise matching - look for the hidden <p> tag with exact title
|
# More precise matching - look for the hidden <p> tag with exact title
|
||||||
match = [html_row for html_row in self.prev_html
|
match = [html_row for html_row in self.prev_html
|
||||||
if f'<p hidden>{movie["title"]}</p>' in html_row
|
if f'<p hidden>{movie["title"]}</p>' in html_row
|
||||||
and 'N/A' not in html_row]
|
and 'N/A' not in html_row]
|
||||||
if match:
|
if match:
|
||||||
# Update the index and status from the cached row
|
# Update the index and status from the cached row
|
||||||
@@ -478,7 +450,15 @@ class MovieList:
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.delete_finished_threads()
|
self.delete_finished_threads()
|
||||||
|
|
||||||
# Don't append to self.html here - we'll do it in write()
|
self.html += ''.join(self.html_table)
|
||||||
|
|
||||||
|
# Deduplicate entries before writing
|
||||||
|
num_entries = self.deduplicate_html()
|
||||||
|
print(f"\nDeduplicated to {num_entries} unique entries")
|
||||||
|
|
||||||
|
self.html = self.html.split('</tbody>')[0] # Remove everything after tbody if it exists
|
||||||
|
self.html += ''.join(self.html_table)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def delete_finished_threads(self):
|
def delete_finished_threads(self):
|
||||||
@@ -499,42 +479,37 @@ class MovieList:
|
|||||||
""" Write the HTML list to index.html """
|
""" Write the HTML list to index.html """
|
||||||
out_path = dst if dst else self.dst
|
out_path = dst if dst else self.dst
|
||||||
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
|
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
|
||||||
|
self.html += f'''
|
||||||
# Build the final HTML - don't append, rebuild from scratch
|
|
||||||
final_html = self.html.split('<tbody>')[0] + '<tbody>'
|
|
||||||
final_html += ''.join([row for row in self.html_table if row is not None])
|
|
||||||
final_html += f'''
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="timestamp">Generated {timestamp} UTC</div>
|
<div class="timestamp">Generated {timestamp} UTC</div>
|
||||||
</body>
|
</body>
|
||||||
</html>'''
|
</html>'''
|
||||||
|
|
||||||
with open(out_path, 'wb') as fp_handle:
|
with open(out_path, 'wb') as fp_handle:
|
||||||
fp_handle.write(final_html.encode('utf8'))
|
fp_handle.write(self.html.encode('utf8'))
|
||||||
|
|
||||||
def read_prev_output(self):
|
def read_prev_output(self):
|
||||||
""" Import a previous HTML table """
|
""" Import a previous HTML table """
|
||||||
if self.dst.exists():
|
if self.dst.exists():
|
||||||
with open(self.dst, 'rb') as fp_handle:
|
with open(self.dst, 'rb') as fp_handle:
|
||||||
self.prev_html = fp_handle.read().decode('utf8').split('\n')
|
self.prev_html = fp_handle.read().decode('utf8').split('\n')
|
||||||
|
|
||||||
def deduplicate_html(self):
|
def deduplicate_html(self):
|
||||||
""" Remove duplicate entries from html_table based on movie titles """
|
""" Remove duplicate entries from html_table based on movie titles """
|
||||||
seen_titles = set()
|
seen_titles = set()
|
||||||
deduplicated = []
|
deduplicated = []
|
||||||
|
|
||||||
for idx, row in enumerate(self.html_table):
|
for idx, row in enumerate(self.html_table):
|
||||||
if row is None:
|
if row is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Extract the hidden title from the row
|
# Extract the hidden title from the row
|
||||||
if '<p hidden>' in row and '</p>' in row:
|
if '<p hidden>' in row and '</p>' in row:
|
||||||
start = row.find('<p hidden>') + 10
|
start = row.find('<p hidden>') + 10
|
||||||
end = row.find('</p>', start)
|
end = row.find('</p>', start)
|
||||||
title = row[start:end]
|
title = row[start:end]
|
||||||
|
|
||||||
if title not in seen_titles:
|
if title not in seen_titles:
|
||||||
seen_titles.add(title)
|
seen_titles.add(title)
|
||||||
deduplicated.append(row)
|
deduplicated.append(row)
|
||||||
@@ -544,7 +519,7 @@ class MovieList:
|
|||||||
else:
|
else:
|
||||||
# If we can't find the hidden title, keep the row anyway
|
# If we can't find the hidden title, keep the row anyway
|
||||||
deduplicated.append(row)
|
deduplicated.append(row)
|
||||||
|
|
||||||
# Update html_table with deduplicated content
|
# Update html_table with deduplicated content
|
||||||
self.html_table = deduplicated
|
self.html_table = deduplicated
|
||||||
return len(self.html_table)
|
return len(self.html_table)
|
||||||
|
|||||||
@@ -466,4 +466,3 @@ Poor Things (2023) [*]
|
|||||||
The French Dispatch (2021) [DONE]
|
The French Dispatch (2021) [DONE]
|
||||||
Sentimental Value (2025) [DONE]
|
Sentimental Value (2025) [DONE]
|
||||||
28 Years Later: The Bone Temple (2026) [*]
|
28 Years Later: The Bone Temple (2026) [*]
|
||||||
Youth (2015) [DONE]
|
|
||||||
|
|||||||
11
movie_list/scroll-indicator.js
Normal file
11
movie_list/scroll-indicator.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
(function() {
|
||||||
|
var si = document.querySelector(".scroll-indicator");
|
||||||
|
var onscroll = function() {
|
||||||
|
var max = document.body.scrollHeight - window.innerHeight;
|
||||||
|
si.style.display = "block";
|
||||||
|
si.style.width = (window.pageYOffset / max * 100) + "%";
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onscroll = onscroll;
|
||||||
|
onscroll();
|
||||||
|
})();
|
||||||
41
movie_list/style.css
Normal file
41
movie_list/style.css
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
.scroll-indicator {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 50%;
|
||||||
|
height: 10px;
|
||||||
|
background: #C33;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
cursor:pointer;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 1px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
font-family: arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #3D3635;
|
||||||
|
font-family: arial, sans-serif;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #3D3635;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:link, a:visited {
|
||||||
|
background-color: #3D3635;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user