Improve Web interface
Merge pull request #56 from KagurazakaNyaa/master
This commit is contained in:
10 files changed
+212
-130
No files matched your search
@@ -108,3 +108,6 @@ venv.bak/
|
|||||||
configuration.ini
|
configuration.ini
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
2019-07-27 22_09_08-radiobrowser.py - botamusique - Visual Studio Code.png
|
2019-07-27 22_09_08-radiobrowser.py - botamusique - Visual Studio Code.png
|
||||||
|
|
||||||
|
music_folder/
|
||||||
|
tmp/
|
||||||
@@ -11,7 +11,7 @@ username = botamusique
|
|||||||
comment = Hi, I'm here to play radio, local music or youtube/soundcloud music. Have fun !
|
comment = Hi, I'm here to play radio, local music or youtube/soundcloud music. Have fun !
|
||||||
volume = 0.1
|
volume = 0.1
|
||||||
admin = User1;User2; # Allow user to kill the bot
|
admin = User1;User2; # Allow user to kill the bot
|
||||||
music_folder = /home/azlux/botamusique/music_folder/
|
music_folder = music_folder/
|
||||||
tmp_folder = /tmp/
|
tmp_folder = /tmp/
|
||||||
pip3_path = venv/bin/pip
|
pip3_path = venv/bin/pip
|
||||||
auto_update = True
|
auto_update = True
|
||||||
|
|||||||
+8
-5
@@ -122,6 +122,7 @@ def index():
|
|||||||
user=var.user)
|
user=var.user)
|
||||||
|
|
||||||
|
|
||||||
|
@web.route('/upload', methods=["POST"])
|
||||||
def upload():
|
def upload():
|
||||||
file = request.files['file']
|
file = request.files['file']
|
||||||
if not file:
|
if not file:
|
||||||
@@ -137,14 +138,15 @@ def upload():
|
|||||||
elif '../' in targetdir:
|
elif '../' in targetdir:
|
||||||
return redirect("./", code=406)
|
return redirect("./", code=406)
|
||||||
|
|
||||||
# print('Uploading file:')
|
print('Uploading file:')
|
||||||
# print('filename:', filename)
|
print('filename:', filename)
|
||||||
# print('targetdir:', targetdir)
|
print('targetdir:', targetdir)
|
||||||
# print('mimetype:', file.mimetype)
|
print('mimetype:', file.mimetype)
|
||||||
|
|
||||||
if "audio" in file.mimetype:
|
if "audio" in file.mimetype:
|
||||||
storagepath = os.path.abspath(os.path.join(var.music_folder, targetdir))
|
storagepath = os.path.abspath(os.path.join(var.music_folder, targetdir))
|
||||||
if not storagepath.startswith(var.music_folder):
|
print('storagepath:',storagepath)
|
||||||
|
if not storagepath.startswith(os.path.abspath(var.music_folder)):
|
||||||
return redirect("./", code=406)
|
return redirect("./", code=406)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -154,6 +156,7 @@ def upload():
|
|||||||
return redirect("./", code=500)
|
return redirect("./", code=500)
|
||||||
|
|
||||||
filepath = os.path.join(storagepath, filename)
|
filepath = os.path.join(storagepath, filename)
|
||||||
|
print('filepath:',filepath)
|
||||||
if os.path.exists(filepath):
|
if os.path.exists(filepath):
|
||||||
return redirect("./", code=406)
|
return redirect("./", code=406)
|
||||||
|
|
||||||
|
|||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
/*!
|
||||||
|
* Bootstrap v4.3.1 (https://getbootstrap.com/)
|
||||||
|
* Copyright 2011-2019 The Bootstrap Authors
|
||||||
|
* Copyright 2011-2019 Twitter, Inc.
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
*/:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,Line truncated
|
||||||
|
/*# sourceMappingURL=bootstrap.min.css.map */
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sources":["../../scss/bootstrap.scss","../../scss/_root.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","../../scss/vendor/_rfs.scss","bootstrap.css","../../scss/mixins/_hover.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/mixins/_border-radius.scss","../../scss/_code.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/_tables.scss","../../scss/mixins/_table-row.scss","../../scss/_forms.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_forms.scss","../../scss/mixins/_gradients.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/mixins/_nav-divider.scss","../../scss/_button-group.scss","../../scss/_input-group.scss","../../scss/_custom-forms.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/mixins/_badge.scss","../../scss/_jumbotron.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_media.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/utilities/_align.scss","../../scss/mixins/_background-variant.scss","../../scss/utilities/_background.scss","../../scss/utilities/_borders.scss","../../scss/utilities/_display.scss","../../scss/utilities/_embed.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_float.scss","../../scss/utilities/_overflow.scss","../../scss/utilities/_position.scss","../../scss/utilities/_screenreaders.scss","../../scss/mixins/_screen-reader.scss","../../scss/utilities/_shadows.scss","../../scss/utilities/_sizing.scss","../../scss/utilities/_stretched-link.scss","../../scss/utilities/_spacing.scss","../../scss/utilities/_text.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_text-emphasis.scss","../../scss/mixins/_text-hide.scss","../../scss/utilities/_visibility.scss","../../scss/_print.scss"],"names":[],"mappings":"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 truncated
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/* necessary to place both forms/buttons next to each other */
|
|
||||||
li.file {
|
|
||||||
clear: both;
|
|
||||||
list-style-position: outside;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* necessary to place both forms/buttons next to each other */
|
|
||||||
form.file {
|
|
||||||
/* Float both forms to the left */
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.file.file_add {
|
|
||||||
margin-left: 5px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* necessary to place both forms/buttons next to each other */
|
|
||||||
form.file.file_download {
|
|
||||||
clear: right;
|
|
||||||
/* with some space to the left of the second form */
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* necessary to place all forms/buttons of the directory entries next to each other */
|
|
||||||
li.directory {
|
|
||||||
clear: both;
|
|
||||||
list-style-position: outside;
|
|
||||||
margin-top: 15px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
li.directory span {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.directory {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.directory.form1 {
|
|
||||||
margin-left: 5px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.directory.form2 {
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.directory.form3 {
|
|
||||||
clear: right;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
/*!
|
||||||
|
* Bootstrap v4.3.1 (https://getbootstrap.com/)
|
||||||
|
* Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
*/
|
||||||
|
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery")):"function"==typeof define&&define.amd?define(["exports","jquery"],e):e((t=t||self).bootstrap={},t.jQuery)}(this,function(t,p){"use strict";function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function s(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),t}function l(o){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},e=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(e=e.concat(Object.getOwnPropertySymbols(r).filter(function(t){return Object.getOwnPropertyDescriptor(r,t).enumerable}))),e.forEach(function(t){var e,n,i;e=o,i=r[n=t],n in e?Object.defineProperty(e,n,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[n]=i})}return o}p=p&&p.hasOwnProperty("default")?p.default:p;var e="transitionend";function n(t){var e=this,n=!1;return p(this).one(m.TRANSITION_END,function(){n=!0}),setTimeout(function(){n||m.triggerTransitionEnd(e)},t),this}var m={TRANSITION_END:"bsTransitionEnd",getUID:function(t){for(;t+=~~(1e6*Math.random()),document.getElementById(t););return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var e=p(t).css("transition-duration"),n=p(t).css("transition-delay"),i=parseFloat(e),o=parseFloat(n);return i||o?(e=e.split(",")[0],n=n.split(",")[0],1e3*(parseFloat(e)+parseFloat(n))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){p(t).trigger(e)},supportsTransitionEnd:function(){return Boolean(e)},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],r=e[i],s=r&&m.isElement(r)?"element":(a=r,{}.toString.call(a).match(/\s([a-z]+)/i)[1].toLowerCase());if(!new RegExp(o).test(s))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+s+'" but expected type "'+o+'".')}var a},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"!=typeof t.getRootNode)return t instanceof ShadowRoot?t:t.parentNode?m.findShadowRoot(t.parentNode):null;var e=t.getRootNode();return e instanceof ShadowRoot?e:null}};p.fn.emulateTransitionEnd=n,p.event.special[m.TRANSITION_END]={bindType:e,delegateType:e,handle:function(t){if(p(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var o="alert",r="bs.alert",a="."+r,c=p.fn[o],h={CLOSE:"close"+a,CLOSED:"closed"+a,CLICK_DATA_API:"click"+a+".data-api"},u="alert",f="fade",d="show",g=function(){function i(t){this._element=t}var t=i.prototype;return t.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},t.dispose=function(){p.removeData(this._element,r),this._element=null},t._getRootElement=function(t){var e=m.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=p(t).closest("."+u)[0]),n},t._triggerCloseEvent=function(t){var e=p.Event(h.CLOSE);return p(t).trigger(e),e},t._removeElement=function(e){var n=this;if(p(e).removeClass(d),p(e).hasClass(f)){var t=m.getTransitionDurationFromElement(e);p(e).one(m.TRANSITION_END,function(t){return n._destroyElement(e,t)}).emulateTransitionEnd(t)}else this._destroyElement(e)},t._destroyElement=function(t){p(t).detach().trigger(h.CLOSED).remove()},i._jQueryInterface=function(n){return this.each(function(){var t=p(this),e=t.data(r);e||(e=new i(this),t.data(r,e)),"close"===n&&e[n](this)})},i._handleDismiss=function(e){return function(t){t&&t.preventDefault(),e.close(this)}},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}}]),i}();p(document).on(h.CLICK_DATA_API,'[data-dismiss="alert"]',g._handleDismiss(new g)),p.fn[o]=g._jQueryInterface,p.fn[o].Constructor=g,p.fn[o].noConflict=function(){return p.fn[o]=c,g._jQueryInterface};var _="button",v="bs.button",y="."+v,E=".data-api",b=p.fn[_],w="active",C="btn",T="focus",S='[data-toggle^="button"]',D='[data-toggle="buttons"]',I='input:not([type="hidden"])',A=".active",O=".btn",N={CLICK_DATA_API:"click"+y+E,FOCUS_BLUR_DATA_API:"focus"+y+E+" blur"+y+E},k=function(){function n(t){this._element=t}var t=n.prototype;return t.toggle=function(){var t=!0,e=!0,n=p(this._element).closest(D)[0];if(n){var i=this._element.querySelector(I);if(i){if("radio"===i.type)if(i.checked&&this._element.classList.contains(w))t=!1;else{var o=n.querySelector(A);o&&p(o).removeClass(w)}if(t){if(i.hasAttribute("disabled")||n.hasAttribute("disabled")||i.classList.contains("disabled")||n.classList.contains("disabled"))return;i.checked=!this._element.classList.contains(w),p(i).trigger("change")}i.focus(),e=!1}}e&&this._element.setAttribute("aria-pressed",!this._element.classLLine truncated
|
||||||
|
//# sourceMappingURL=bootstrap.bundle.min.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../node_modules/popper.js/dist/esm/popper.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js","../../js/src/index.js"],"names":["TRANSITION_END","transitionEndEmulator","duration","_this","this","called","$","one","Util","setTimeout","triggerTransitionEnd","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","err","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","obj","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","call","expectedTypes","value","valueType","toString","match","toLowerCase","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","ShadowRoot","parentNode","root","fn","emulateTransitionEnd","event","special","bindType","delegateType","handle","target","is","handleObj","handler","apply","arguments","NAME","DATA_KEY","EVENT_KEY","JQUERY_NO_CONFLICT","Event","CLOSE","CLOSED","CLICK_DATA_API","ClassName","Alert","_element","close","rootElement","_getRootElement","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","DATA_API_KEY","Selector","FOCUS_BLUR_DATA_API","Button","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","hasAttribute","focus","setAttribute","toggleClass","button","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","Direction","SLIDE","SLID","KEYDOWN","MOUSEENTER","MOUSELEAVE","TOUCHSTART","TOUCHMOVE","TOUCHEND","POINTERDOWN","POINTERUP","DRAG_START","LOAD_DATA_API","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","window","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","length","direction","off","_objectSpread","_handleSwipe","absDeltax","abs","_this2","_keydown","_addTouchEventListeners","_this3","start","originalEvent","pointerType","clientX","touches","end","clearTimeout","querySelectorAll","e","add","tagName","which","slice","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","directionalClassName","orderClassName","_this4","activeElementIndex","nextElement","nextElementIndex","isCycling","slidEvent","nextElementInterval","parseInt","defaultInterval","action","TypeError","ride","_dataApiClickHandler","slideIndex","carousels","i","len","$carousel","SHOW","SHOWN","HIDE","HIDDEN","Dimension","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","scrollSize","getBoundingClientRect","triggerArrayLength","isTransitioning","jquery","_getTargetFromElement","triggerArray","isOpen","$this","currentTarget","$trigger","selectors","$target","isBrowser","longerTimeoutBrowsers","timeoutDuration","userAgent","debounce","Promise","resolve","then","scheduled","isFunction","functionToCheck","getStyleComputedProperty","ownerDocument","defaultView","getComputedStyle","getParentNode","nodeName","host","getScrollParent","body","_getStyleComputedProp","overflow","overflowX","overflowY","isIE11","MSInputMethodContext","documentMode","isIE10","isIE","version","getOffsetParent","noOffsetParent","offsetParent","nextElementSibling","getRoot","node","findCommonOffsetParent","element1","element2","order","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","range","createRange","setStart","setEnd","commonAncestorContainer","firstElementChild","element1root","getScroll","upperSide","undefined","html","scrollingElement","getBordersSize","styles","axiLine truncated
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */
|
||||||
|
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}k.fn=k.prototype={jquery:f,constructor:k,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(n){return this.pushStack(k.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},k.extend=k.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(k.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||k.isPlainObject(n)?n:{},i=!1,a[t]=k.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},k.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t){b(e,{nonce:t&&t.nonce})},each:function(e,t){var n,r=0;if(d(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(p,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?k.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g.apply([],a)},guid:1,support:y}),"function"==typeof Symbol&&(k.fn[Symbol.iterator]=t[Symbol.iterator]),k.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var h=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,k="sizzle"+1*new Date,m=n.document,S=0,r=0,p=ue(),x=ue(),N=ue(),A=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",$=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",F=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+Line truncated
|
||||||
+182
-71
@@ -1,38 +1,47 @@
|
|||||||
{% macro dirlisting(dir, path='') -%}
|
{% macro dirlisting(dir, path='') -%}
|
||||||
<ul>
|
<ul class="list-group">
|
||||||
{% for subdirname, subdirobj in dir.get_subdirs().items() %}
|
{% for subdirname, subdirobj in dir.get_subdirs().items() %}
|
||||||
{%- set subdirpath = os.path.relpath(subdirobj.fullpath, music_library.fullpath) %}
|
{%- set subdirpath = os.path.relpath(subdirobj.fullpath, music_library.fullpath) %}
|
||||||
<li class="directory">
|
{%- set subdirid = subdirpath.replace("/","-") %}
|
||||||
<span>{{ subdirname }}/ </span>
|
<li class="directory list-group-item list-group-item-primary">
|
||||||
<form method="post" class="directory form1">
|
<span>{{ subdirpath }}/ </span>
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<form method="post" class="directory">
|
||||||
<input type="text" value="{{ subdirpath }}" name="add_folder" hidden>
|
<input type="text" value="{{ subdirpath }}" name="add_folder" hidden>
|
||||||
<input type="submit" value="Add all tracks from this folder">
|
<button type="submit" class="btn btn-secondary">Add all tracks from this folder</button>
|
||||||
</form>
|
</form>
|
||||||
<form method="post" class="directory form2">
|
<form method="post" class="directory">
|
||||||
<input type="text" value="{{ subdirpath }}" name="add_folder_recursively" hidden>
|
<input type="text" value="{{ subdirpath }}" name="add_folder_recursively" hidden>
|
||||||
<input type="submit" value="Add all tracks from this folder (recursively)">
|
<button type="submit" class="btn btn-secondary">Add all tracks from this folder (recursively)</button>
|
||||||
</form>
|
</form>
|
||||||
<form action="./download" method="get" class="directory form3">
|
<form action="./download" method="get" class="directory">
|
||||||
<input type="text" value="{{ subdirpath }}" name="directory" hidden>
|
<input type="text" value="{{ subdirpath }}" name="directory" hidden>
|
||||||
<input type="submit" value="Download entire directory">
|
<button type="submit" class="btn btn-secondary">Download entire directory</button>
|
||||||
</form>
|
</form>
|
||||||
|
<button class="btn btn-primary" type="button" data-toggle="collapse"
|
||||||
|
data-target="#multiCollapse-{{ subdirid }}" aria-expanded="true"
|
||||||
|
aria-controls="multiCollapse-{{ subdirid }}">Toggle Collapse</button>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<div class="collapse multi-collapse" id="multiCollapse-{{ subdirid }}">
|
||||||
{{- dirlisting(subdirobj, subdirpath) -}}
|
{{- dirlisting(subdirobj, subdirpath) -}}
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- set files = dir.get_files() %}
|
{%- set files = dir.get_files() %}
|
||||||
{%- if files %}
|
{%- if files %}
|
||||||
{% for file in files %}
|
{% for file in files %}
|
||||||
{% set filepath = os.path.relpath(os.path.join(dir.fullpath, file), music_library.fullpath) %}
|
{% set filepath = os.path.relpath(os.path.join(dir.fullpath, file), music_library.fullpath) %}
|
||||||
<li class="file">
|
<li class="file list-group-item">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
<form method="post" class="file file_add">
|
<form method="post" class="file file_add">
|
||||||
<input type="text" value="{{ filepath }}" name="add_file" hidden>
|
<input type="text" value="{{ filepath }}" name="add_file" hidden>
|
||||||
<input type="submit" value="Add">
|
<button type="submit" class="btn btn-primary">Add</button>
|
||||||
</form>
|
</form>
|
||||||
<form action="./download" method="get" class="file file_download">
|
<form action="./download" method="get" class="file file_download">
|
||||||
<input type="text" value="{{ filepath }}" name="file" hidden>
|
<input type="text" value="{{ filepath }}" name="file" hidden>
|
||||||
<input type="submit" value="Download">
|
<button type="submit" class="btn btn-primary">Download</button>
|
||||||
{{ file }}
|
|
||||||
</form>
|
</form>
|
||||||
|
</div> {{ filepath }}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
@@ -40,87 +49,189 @@
|
|||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title></title>
|
<title>botamusique web interface</title>
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
|
||||||
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
|
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
|
||||||
<META HTTP-EQUIV="Expires" CONTENT="-1">
|
<META HTTP-EQUIV="Expires" CONTENT="-1">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
|
||||||
<a href="."><h5>Refresh</h5></a>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<div id="upload">
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div id="playlist" class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2 class="card-title">Play List</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div>
|
||||||
|
Currently Playing :
|
||||||
|
{% if playlist|length > 0 %}
|
||||||
|
{% if 'url' in playlist[0] %}
|
||||||
|
<a href="{{ playlist[0]['url'] }}">{{ playlist[0]['url'] }}</a>
|
||||||
|
{% elif 'path' in playlist[0] %}
|
||||||
|
{{ playlist[0]['path'] }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
No music
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<form method="post">
|
||||||
|
<input type="text" value="randomize" name="action" hidden>
|
||||||
|
<button type="submit" class="btn btn-primary">Randomize playlist</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Type</th>
|
||||||
|
<th scope="col">Title</th>
|
||||||
|
<th scope="col">Url/Path</th>
|
||||||
|
<th scope="col">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for m in playlist[1:] %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{{ loop.index }}</th>
|
||||||
|
<td>{{ m['type'] }}</td>
|
||||||
|
<td>
|
||||||
|
{% if 'title' in m %}
|
||||||
|
({{ m['title'] }})
|
||||||
|
{% else %}
|
||||||
|
No title
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if 'url' in m %}
|
||||||
|
<a href="{{ m['url'] }}">{{ m['url'] }}</a>
|
||||||
|
{% elif 'path' in m %}
|
||||||
|
{{ m['path'] }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<form method="post">
|
||||||
|
<input type="text" value="{{ loop.index }}" name="delete_music" hidden>
|
||||||
|
<button type="submit" class="btn btn-primary">Remove</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div id="browser" class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2 class="card-title">Music library</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<form action="./download" method="get" class="directory form1">
|
||||||
|
<input type="text" value="./" name="directory" hidden>
|
||||||
|
<button type="submit" class="btn btn-primary">Download entire music library</button>
|
||||||
|
</form>
|
||||||
|
<form method="post" class="directory form3">
|
||||||
|
<input type="text" value="./" name="add_folder_recursively" hidden>
|
||||||
|
<button type="submit" class="btn btn-primary">Add all tracks from music library
|
||||||
|
(recursively)</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
{{ dirlisting(music_library) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="upload" class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="card-title">Upload File</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
<form action="./upload" method="post" enctype="multipart/form-data">
|
<form action="./upload" method="post" enctype="multipart/form-data">
|
||||||
<input type="file" name="file" value="Browse Music file"/>
|
<div class="input-group">
|
||||||
Upload into
|
<div class="custom-file">
|
||||||
<input list="targetdirs" id="targetdir" name="targetdir" placeholder="uploads" />
|
<input type="file" name="file" class="custom-file-input" id="uploadSelectFile"
|
||||||
|
aria-describedby="uploadSubmit" value="Browse Music file" />
|
||||||
|
<label class="custom-file-label" for="uploadSelectFile">Choose file</label>
|
||||||
|
</div>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<span class="input-group-text">Upload To</span>
|
||||||
|
<input class="form-control" list="targetdirs" id="targetdir" name="targetdir"
|
||||||
|
placeholder="uploads" />
|
||||||
<datalist id="targetdirs">
|
<datalist id="targetdirs">
|
||||||
<option value="uploads">
|
<option value="uploads">
|
||||||
{% for dir in music_library.get_subdirs_recursively() %}
|
{% for dir in music_library.get_subdirs_recursively() %}
|
||||||
<option value="{{ dir }}">
|
<option value="{{ dir }}">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</datalist>
|
</datalist>
|
||||||
<input type="submit" value="Upload"/>
|
<button class="btn btn-outline-secondary" type="submit"
|
||||||
|
id="uploadSubmit">Upload</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div id="url">
|
</div>
|
||||||
Add Youtube/Soundcloud URL :
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="card-title">Add URL</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type=text name="add_url">
|
<label>Add Youtube/Soundcloud URL :</label>
|
||||||
<input type="submit" value="Add URL">
|
<input class="form-control" type="text" name="add_url">
|
||||||
|
<button type="submit" class="btn btn-primary">Add URL</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="radio">
|
</div>
|
||||||
Add Radio URL :
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="card-title">Add Radio</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type=text name="add_radio">
|
<label>Add Radio URL :</label>
|
||||||
<input type="submit" value="Add Radio">
|
<input class="form-control" type="text" name="add_radio">
|
||||||
|
<button type="submit" class="btn btn-primary">Add Radio</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="playlist">
|
|
||||||
Currently Playing :
|
|
||||||
{% if playlist|length > 0 %}
|
|
||||||
{{ playlist[0]['title'] }} {{ playlist[0]['user'] }}
|
|
||||||
{% if 'url' in playlist[0] %}
|
|
||||||
(<a href="{{ playlist[0]['url'] }}">{{ playlist[0]['url'] }}</a>)
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
No music
|
|
||||||
{% endif %}
|
|
||||||
<br />
|
|
||||||
Playlist :
|
|
||||||
<form method="post"><input type="text" value="randomize" name="action" hidden><input type="submit" value="Randomize playlist"></form>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
{% for m in playlist[1:] %}
|
|
||||||
<li>[{{ m['type'] }}]] {{ m['title'] }} - {{ m['url'] }}
|
|
||||||
<form method="post"><input type="text" value="{{ loop.index }}" name="delete_music" hidden><input type="submit" value="X"></form>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
<h2>Music library:</h2>
|
|
||||||
<form action="./download" method="get" class="directory form1">
|
|
||||||
<input type="text" value="./" name="directory" hidden>
|
|
||||||
<input type="submit" value="Download entire music library">
|
|
||||||
</form>
|
|
||||||
<form method="post" class="directory form3">
|
|
||||||
<input type="text" value="./" name="add_folder_recursively" hidden>
|
|
||||||
<input type="submit" value="Add all tracks from music library (recursively)">
|
|
||||||
</form>
|
|
||||||
<br />
|
|
||||||
{{ dirlisting(music_library) }}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="browser">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="upload">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/static/js/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
|
||||||
|
<script src="/static/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
|
||||||
|
<script>
|
||||||
|
$('#uploadSelectFile').on('change', function () {
|
||||||
|
//get the file name
|
||||||
|
var fileName = $(this).val().replace('C:\\fakepath\\', " ");
|
||||||
|
//replace the "Choose a file" label
|
||||||
|
$(this).next('.custom-file-label').html(fileName);
|
||||||
|
})
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Reference in new issue
Block a user