| New file |
| | |
| | | package com.shsening.autouploadvideos |
| | | |
| | | |
| | | import android.app.Instrumentation |
| | | import android.content.Context |
| | | import android.os.SystemClock |
| | | import android.os.Handler |
| | | import com.shsening.autouploadvideos.UploadSessionActivity |
| | | import com.shsening.autouploadvideos.utils.Utils |
| | | import com.shsening.autouploadvideos.WebviewUtils |
| | | import com.shsening.autouploadvideos.action.PlatformActionInterface |
| | | |
| | | class ActionBilibili (private var activity: UploadSessionActivity, private var threadHandler: Handler, private var videoInfo: Utils.VideoUploadTaskInfo) : |
| | | PlatformActionInterface { |
| | | |
| | | |
| | | private var webView = activity.sessionProfileWebView |
| | | |
| | | |
| | | var jsCode_CheckContentLoaded = """ |
| | | document.querySelector('#video-up-app > div.video-entrance > div.upload-body > div > div.upload-wrp > div.bcc-upload.upload > div > input[type=file]') !== null |
| | | """.trimIndent() |
| | | var jsCode_CheckVideoUploadFinished = """ |
| | | document.querySelector('#video-up-app > div.video-basic-wrp > div.video-basic > div.video-upload > div.upload-queue > div > div.file-list > div.drag-list > div > div > div.file-item-content > div.file-item-content-detail > div.file-item-content-operate > div > div') !==null |
| | | """.trimIndent() |
| | | var jsCode_PublishVideo_Finished ="document.querySelector('#video-up-app > div.video-entrance > div.upload-body > div > div.banner-entry > div.banner-entry-right > div') !== null" |
| | | |
| | | var jsPath_PublishVideo ="#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(17) > div > div > span" |
| | | |
| | | |
| | | |
| | | private fun updatePostDescription(){ |
| | | |
| | | WebviewUtils.addValueToInput(webView,"#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div.form-item.form-item-short-margin > div > div.video-title-content > div.input.input-container > div > input",videoInfo.title+videoInfo.datetime) |
| | | |
| | | WebviewUtils.addValueToDiv(webView,"#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(7) > div > div.desc-text-wrp > div > div.editor.ql-container > div.ql-editor.ql-blank",videoInfo.description) |
| | | |
| | | |
| | | WebviewUtils.simpleElementClick(webView,"#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div") |
| | | val datetime1 = videoInfo.datetime.substring(0,8) |
| | | val datetime2 = videoInfo.datetime.substring(8) |
| | | setDatePickerInput("#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div.time-picker > div > div > div:nth-child(2) > div",datetime1) |
| | | setTimePickerInput("#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div.time-picker > div > div > div:nth-child(3) > div",datetime2) |
| | | |
| | | // å¨ä¸»çº¿ç¨ä¸è®¾ç½®å»¶è¿æ§è¡ |
| | | threadHandler.postDelayed(Runnable { |
| | | startToPublishVideo() |
| | | }, 5000) |
| | | } |
| | | |
| | | |
| | | override fun checkIfContentLoaded() { |
| | | webView.postDelayed({ |
| | | webView.evaluateJavascript(jsCode_CheckContentLoaded) { result -> |
| | | if (result == "true") { |
| | | simulateSwipeAndUploadVideo() |
| | | } else { |
| | | webView.postDelayed({ |
| | | checkIfContentLoaded() |
| | | }, 1000) // 1ç§å忬¡æ£æ¥ |
| | | } |
| | | } |
| | | }, 1000) // æ¯ç§æ£æ¥ä¸æ¬¡ |
| | | } |
| | | |
| | | private fun startToPublishVideo(){ |
| | | WebviewUtils.simpleElementClick(webView, jsPath_PublishVideo) |
| | | |
| | | checkVideoPublishFinished() |
| | | } |
| | | |
| | | private fun checkVideoUploadFinished(){ |
| | | webView.postDelayed({ |
| | | webView.evaluateJavascript(jsCode_CheckVideoUploadFinished) { result -> |
| | | if (result == "true") { |
| | | // çå¾
è§é¢æ£æµåçæå°é¢ |
| | | threadHandler.postDelayed({updatePostDescription()},3000) |
| | | |
| | | } else { |
| | | // å
ç´ ä¸åå¨ï¼1ç§å忬¡æ£æ¥ |
| | | webView.postDelayed({ |
| | | checkVideoUploadFinished() |
| | | }, 1000) // 1ç§å忬¡æ£æ¥ |
| | | } |
| | | } |
| | | }, 1000) // æ¯ç§æ£æ¥ä¸æ¬¡ |
| | | } |
| | | |
| | | private fun checkVideoPublishFinished(){ |
| | | webView.postDelayed({ |
| | | webView.evaluateJavascript(jsCode_PublishVideo_Finished) { result -> |
| | | if (result == "true") { |
| | | |
| | | // video published successfully!!! |
| | | activity.checkAndStartNextTask() |
| | | |
| | | |
| | | } else { |
| | | // å
ç´ ä¸åå¨ï¼1ç§å忬¡æ£æ¥ |
| | | webView.postDelayed({ |
| | | checkVideoPublishFinished() |
| | | }, 1000) // 1ç§å忬¡æ£æ¥ |
| | | } |
| | | } |
| | | }, 1000) // æ¯ç§æ£æ¥ä¸æ¬¡ |
| | | } |
| | | |
| | | private fun setDatePickerInput(jsPath: String, targetValue: String) { |
| | | var datetimes = Utils.validateAndReturnDateTime(targetValue) ?: return |
| | | var dpPanelText = datetimes[0].toString()+"å¹´"+datetimes[1].toString()+"æ"; |
| | | var dateRowColum = Utils.getDatePosition(datetimes[0],datetimes[1],datetimes[2])?:return; |
| | | |
| | | val jsCode = """ |
| | | try { |
| | | var dp = document.querySelector('${jsPath}'); |
| | | dp.focus(); // ç¡®ä¿è¾å
¥æ¡è·å¾ç¦ç¹ |
| | | dp.click(); |
| | | |
| | | // need time to popup date-picker |
| | | setTimeout(() => { |
| | | var dpPanel = document.querySelector('.date-picker-container'); |
| | | var dpPanelSpan = dpPanel.querySelector('div > p'); |
| | | if (dpPanelSpan && dpPanelSpan.textContent != '${dpPanelText}'){ |
| | | document.querySelector('#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div.time-picker > div > div > div:nth-child(2) > div.date-picker-container > div.date-picker-nav-wrp > svg.next-btn-day.icon-sprite.icon-sprite-ic_into').click(); |
| | | } |
| | | document.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-month > div.semi-datepicker-weeks > div:nth-child(${dateRowColum[0]}) > div:nth-child(${dateRowColum[1]})').click() |
| | | |
| | | //switch to time selection |
| | | document.querySelector('#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div.time-picker > div > div > div:nth-child(2) > div.date-picker-container > div.date-picker-nav-wrp > svg.next-btn-day.icon-sprite.icon-sprite-ic_into').click(); |
| | | setTimeout(() => { |
| | | dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-hour > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[3]+1)})').click(); |
| | | dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-minute > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[4]+1)})').click(); |
| | | }, 500); |
| | | }, 500); |
| | | } catch (error) { |
| | | console.error('è®¾ç½®æ¥ææ¶åçé误:', error); |
| | | } |
| | | """.trimIndent() |
| | | |
| | | // å¨ WebView 䏿§è¡ JavaScript 代ç |
| | | webView.evaluateJavascript(jsCode, null) |
| | | } |
| | | |
| | | private fun setTimePickerInput(jsPath: String, targetValue: String) { |
| | | // è§£æåç§å符串ï¼åè®¾æ ¼å¼ä¸º "MMSS" |
| | | val minutes = targetValue.substring(0, 2).toIntOrNull() ?: return // è·åå两个å符ä½ä¸ºåéï¼å¦æè½¬æ¢å¤±è´¥åè¿å |
| | | val seconds = targetValue.substring(2, 4).toIntOrNull() ?: return // è·åå两个å符ä½ä¸ºç§ï¼å¦æè½¬æ¢å¤±è´¥åè¿å |
| | | |
| | | // æå»ºè¦æ§è¡ç JavaScript 代ç |
| | | val jsCode = """ |
| | | try { |
| | | |
| | | setTimeout(() => { |
| | | var minuteSelector = document.querySelector('.minute-selector-class'); |
| | | var secondSelector = document.querySelector('.second-selector-class'); |
| | | |
| | | if (minuteSelector && secondSelector) { |
| | | minuteSelector.value = ${minutes}; |
| | | secondSelector.value = ${seconds}; |
| | | } |
| | | }, 500); // å»¶è¿æ¶é´å¯è½éè¦æ ¹æ®å®é
æ
åµè°æ´ |
| | | } catch (error) { |
| | | console.error('设置æ¶é´æ¶åçé误:', error); |
| | | } |
| | | """.trimIndent() |
| | | |
| | | // å¨ WebView 䏿§è¡ JavaScript 代ç |
| | | webView.evaluateJavascript(jsCode, null) |
| | | } |
| | | private fun addValueToDatePickerInput(first:Boolean, jsPath: String, targetValue: String) { |
| | | |
| | | var datetimes = Utils.validateAndReturnDateTime(targetValue) ?: return |
| | | |
| | | var dpPanelText = datetimes[0].toString()+"å¹´ "+datetimes[1].toString()+"æ"; |
| | | |
| | | var dateRowColum = Utils.getDatePosition(datetimes[0], datetimes[1], datetimes[2]) ?:return; |
| | | |
| | | val jsCode = """ |
| | | try { |
| | | var dp = document.querySelector('${jsPath}'); |
| | | dp.focus(); // ç¡®ä¿è¾å
¥æ¡è·å¾ç¦ç¹ |
| | | dp.click(); |
| | | |
| | | // need time to popup date-picker |
| | | setTimeout(() => { |
| | | var dpPanel = document.querySelector('.semi-popover-content'); |
| | | var dpPanelSpan = dpPanel.querySelector('div > div > div > div:nth-child(1) > div.semi-datepicker-navigation > div > button > span > span'); |
| | | if (dpPanelSpan && dpPanelSpan.textContent != '${dpPanelText}'){ |
| | | dpPanel.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-navigation > button:nth-child(3)').click(); |
| | | } |
| | | dpPanel.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-month > div.semi-datepicker-weeks > div:nth-child(${dateRowColum[0]}) > div:nth-child(${dateRowColum[1]})').click() |
| | | |
| | | //switch to time selection |
| | | dpPanel.querySelector('div > div > div > div > div.semi-datepicker-switch > div.semi-datepicker-switch-time').click(); |
| | | setTimeout(() => { |
| | | dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-hour > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[3]+1)})').click(); |
| | | dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-minute > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[4]+1)})').click(); |
| | | }, 500); |
| | | }, 500); |
| | | } catch (error) { |
| | | console.error('åçé误:', error); |
| | | } |
| | | """ |
| | | webView.evaluateJavascript(jsCode,null) |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | private fun simulateSwipeAndUploadVideo() { |
| | | val instrumentation = Instrumentation() |
| | | val displayMetrics = activity.resources.displayMetrics |
| | | val width = displayMetrics.widthPixels |
| | | val height = displayMetrics.heightPixels |
| | | |
| | | val startX = width.toFloat() * 0.9f // ä»å³ä¾§æ»å¨ |
| | | val endX = width.toFloat() * 0.1f // æ»å¨å°å·¦ä¾§ |
| | | val y = height / 3f // Y åæ å¨å±å¹ä¸é´ |
| | | |
| | | Thread { |
| | | Utils.instrumentationSwipe(instrumentation, startX, y, endX, y) |
| | | SystemClock.sleep(500) |
| | | Utils.instrumentationSwipe(instrumentation, startX, y, endX, y) |
| | | SystemClock.sleep(500) |
| | | Utils.instrumentationClick(instrumentation, width / 2f, height * 2 / 4f) |
| | | // back to main thread |
| | | threadHandler.post { |
| | | checkVideoUploadFinished() |
| | | } |
| | | }.start() |
| | | } |
| | | |
| | | } |