bot.register_command(constants.commands('remove_tag'), cmd_remove_tag)
bot.register_command(constants.commands('find_tagged'), cmd_find_tagged)
bot.register_command(constants.commands('drop_database'), cmd_drop_database, True)
- bot.register_command(constants.commands('recache'), cmd_refresh_cache, True)
+ bot.register_command(constants.commands('rescan'), cmd_refresh_cache, True)
# Just for debug use
bot.register_command('rtrms', cmd_real_time_rms, True)
def cmd_refresh_cache(bot, user, text, command, parameter):
global log
var.library.build_dir_cache(bot)
- log.info("command: cache refreshed.")
+ log.info("command: Local file cache refreshed.")
bot.send_msg(constants.strings('cache_refreshed'), text)
# Just for debug use
ducking_volume = duckv
drop_database = dropdatabase
-recache = recache
+rescan = rescan
[strings]
current_volume = Current volume: {volume}.
<ul>
<li> <b>!<u>n</u>ow </b> (or <b>!np</b>) - display the current song </li>
<li> <b>!<u>q</u>ueue </b> - display items in the playlist </li>
- <li> <b>!file </b>(or <b>!f</b>) {path/folder/index/keyword} - append file to the playlist by its path or index returned by !listfile </li>
+ <li> <b>!file </b>(or <b>!f</b>) {path/folder/index/keyword} - add a single file to the playlist by its path or index returned by !listfile </li>
<li> <b>!<u>filem</u>atch </b>(or <b>!fm</b>) {pattern} - add all files that match regex {pattern} </li>
- <li> <b>!<u>ur</u>l </b> {url} - append youtube or soundcloud music to the playlist </li>
- <li> <b>!<u>playl</u>ist </b> {url} [{offset}] - append items in a youtube or soundcloud playlist, and start with the {offset}-th item </li>
+ <li> <b>!<u>ur</u>l </b> {url} - add Youtube or SoundCloud music </li>
+ <li> <b>!<u>playl</u>ist </b> {url} [{offset}] - add all items in a Youtube or SoundCloud playlist, and start with the {offset}-th item </li>
+ <li> <b>!<u>t</u>ag </b> {tags} - add all items with tags {tags}, tags separated by ",". </li>
<li> <b>!rm </b> {num} - remove the num-th song on the playlist </li>
<li> <b>!<u>rep</u>eat </b> [{num}] - repeat current song {num} (1 by default) times.</li>
<li> <b>!<u>ran</u>dom </b> - randomize the playlist.</li>
<li> <b>!<u>yp</u>lay </b> {index/keywords} - play an item from the list returned by <i>!ytquery</i>, or add the
first search result of {keywords} into the playlist.</li>
</ul>
+ <b>Tag</b>
+ <li> <b>!<u>addt</u>ag </b> {index} {tags} - add {tags} to {index}-th item on the playlist, tags separated by ",". </li>
+ <li> <b>!<u>addt</u>ag </b> * {tags} - add {tags} to all items on the playlist. </li>
+ <li> <b>!<u>un</u>tag </b> {index/*} {tags} - remove {tags} from {index}-th item on the playlist. </li>
+ <li> <b>!<u>un</u>tag </b> {index/*} * - remove all tags from {index}-th item on the playlist. </li>
+ <li> <b>!<u>fin</u>dtagged </b> (or <b>!ft</b>) {tags} - find item with {tags} in the music library. </li>
<b>Other</b>
<ul>
<li> <b>!<u>j</u>oinme {token} </b> - join your own channel with {token}.</li>
<li><b>!<u>urlb</u>an </b> {url} - ban an url</li>
<li><b>!<u>urlu</u>nban </b> {url} - unban an url</li>
<li><b>!<u>urlu</u>nban </b> {url} - unban an url</li>
- <li><b>!recache </b> {url} - rebuild local music file cache</li>
+ <li><b>!rescan </b> {url} - rebuild local music file cache</li>
<li><b>!dropdatabase</b> - clear the entire database, you will lose all settings and music library.</li>
</ul>
else:
return None
-
def query_music_by_tags(self, tags):
condition = []
filler = []
else:
return None
+ def query_tags_by_id(self, id):
+ conn = sqlite3.connect(self.db_path)
+ cursor = conn.cursor()
+ results = cursor.execute("SELECT tags FROM music "
+ "WHERE id=?", (id, )).fetchall()
+ conn.close()
+
+ if len(results) > 0:
+ tags = results[0][0].strip(",").split(",")
+
+ return tags
+ else:
+ return None
+
def delete_music(self, **kwargs):
condition = []
filler = []
return f(*args, **kwargs)
return decorated
+def build_tags_lookup():
+ lookup = {}
+ for path, id in var.library.file_id_lookup.items():
+ lookup[path] = var.music_db.query_tags_by_id(id)
+
+ return lookup
@web.route("/", methods=['GET'])
@requires_auth
def index():
+ tags_lookup = build_tags_lookup()
return render_template('index.html',
all_files=var.library.files,
+ tags_lookup=tags_lookup,
music_library=var.library.dir,
os=os,
playlist=var.playlist,
var.playlist = media.playlist.get_playlist("autoplay", var.playlist)
var.db.set('playlist', 'playback_mode', "autoplay")
log.info("web: playback mode changed to autoplay.")
+ if action == "rescan":
+ var.library.build_dir_cache(var.bot)
+ log.info("web: Local file cache refreshed.")
elif action == "stop":
var.bot.stop()
elif action == "pause":
.bs-docs-section{margin-top:4em}
.btn-space{margin-right:5px}
-.playlist-title{display:inline-block}
-.playlist-artwork{display:inline-block; margin-left:5px;}
+.playlist-title-td{width:60%}
+.playlist-title{float:left; }
+.playlist-artwork{float:left; margin-left:10px;}
</div>
</div>
- <div class="btn-group lead"><div class="btn-space"><i class="fa fa-music" aria-hidden="true"></i></div> {{ filepath }}</div>
+ <div class="btn-group lead">
+ <div class="btn-space"><i class="fa fa-music" aria-hidden="true"></i></div>
+ {{ filepath }}
+ </div>
+ {% for tag in tags_lookup[filepath] %}
+ <span class="badge badge-warning">{{ tag }}</span>
+ {% endfor %}
<div class="btn-group" style="float: right;">
<form action="./download" method="get" class="file file_download">
<thead>
<tr>
<th scope="col">#</th>
- <th scope="col">Title</th>
+ <th scope="col" class="playlist-title-td">Title</th>
<th scope="col">Url/Path</th>
<th scope="col">Action</th>
</tr>
<div class="card-body">
<div class="btn-group" style="margin-bottom: 5px;" role="group">
+ <button type="submit" class="btn btn-secondary btn-space"
+ onclick="request('/post', {action : 'rescan'}); location.reload()">
+ <i class="fas fa-sync-alt" aria-hidden="true"></i> Rescan Files
+ </button>
<form action="./download" method="get" class="directory form1">
<input type="text" value="./" name="directory" hidden>
<button type="submit" class="btn btn-secondary btn-space"><i class="fa fa-download" aria-hidden="true"></i> Download All</button>
<b>{{ m.url|truncate(45) }}</b>
{% endif %}
<span class="badge badge-secondary">{{ m.display_type() }}</span>
- <br>
+ <br />
{% if m.type == 'file' %}
{% if m.artist %}
{{ m.artist }}
{% else %}
Unknown Artist
{% endif %}
+ <br />
+ {% for tag in m.tags %}
+ <span class="badge badge-warning">{{ tag }}</span>
+ {% endfor %}
</div>
</td>
<td>