cshenfu
2024-12-06 fb6848decc0fdf3ddacbc9e57692f1fe0314df93
shipinhao_btn
1个文件已删除
4个文件已添加
1个文件已修改
744 ■■■■■ 已修改文件
.idea/appInsightsSettings.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/deploymentTargetSelector.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/other.xml 329 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/shsening/autouploadvideos/action/ActionBilibili.kt 233 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/shsening/autouploadvideos/action/ActionRedbook.kt 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
未命名 补丁 | 查看 | 原始文档 | blame | 历史
.idea/appInsightsSettings.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="AppInsightsSettings">
    <option name="selectedTabId" value="Android Vitals" />
  </component>
</project>
.idea/deploymentTargetSelector.xml
@@ -13,9 +13,6 @@
        </DropdownSelection>
        <DialogSelection />
      </SelectionState>
      <SelectionState runConfigName="SessionProfileActivity">
        <option name="selectionMode" value="DROPDOWN" />
      </SelectionState>
    </selectionStates>
  </component>
</project>
.idea/other.xml
File was deleted
app/src/main/java/com/shsening/autouploadvideos/action/ActionBilibili.kt
New file
@@ -0,0 +1,233 @@
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()
    }
}
app/src/main/java/com/shsening/autouploadvideos/action/ActionRedbook.kt
New file
@@ -0,0 +1,173 @@
package com.shsening.autouploadvideos
import android.app.Instrumentation
import android.content.Context
import android.os.SystemClock
import android.os.Handler
import android.os.Bundle
import android.os.Looper
import androidx.appcompat.app.AppCompatActivity
import com.shsening.autouploadvideos.action.PlatformActionInterface
import com.shsening.autouploadvideos.utils.Utils
class ActionRedbook (private var activity: UploadSessionActivity, private var threadHandler: Handler, private var videoInfo: Utils.VideoUploadTaskInfo):
    PlatformActionInterface {
    private var webView = activity.sessionProfileWebView
    var jsCode_CheckContentLoaded = """
        document.querySelector('input[type="file"][class="upload-input"]') !== null
    """.trimIndent()
    var jsCode_CheckVideoUploadFinished = """
        document.querySelector("#publish-container > div.post-page > div.body > div.content > div.media-area-new > div > div > div.content > div.operator > span:nth-child(1)") !==null
    """.trimIndent()
    var jsCode_PublishVideo_Finished ="document.querySelector('#web > div > div > div > div.upload-content > div.tips-wrapper > div:nth-child(3) > div > p:nth-child(3)') !== null"
    var jsPath_PublishVideo ="button.publishBtn"
    private fun updatePostDescription(){
        WebviewUtils.addValueToInput(webView,"#publish-container > div > div.body > div.content > div.input.titleInput > div.d-input-wrapper.d-inline-block.c-input_inner > div > input",videoInfo.title)
        WebviewUtils.addValueToDiv(webView,"#quillEditor > div > p",videoInfo.description)
        WebviewUtils.simpleElementClick(webView,"#topicBtn")
        SystemClock.sleep(500)
        WebviewUtils.simpleElementClick(webView,"#quill-mention-item-0")
        WebviewUtils.simpleElementClick(webView,"#topicBtn")
        SystemClock.sleep(500)
        WebviewUtils.simpleElementClick(webView,"#quill-mention-item-1")
//        WebviewUtils.simpleElementClick(webView,"#el-id-3410-26 > label:nth-child(1)")
        WebviewUtils.simpleElementClick(webView,"html > body > div:nth-of-type(1) > div > div:nth-of-type(2) > div > div:nth-of-type(2) > main > div:nth-of-type(3) > div > div > div:nth-of-type(1) > div > div > div > div:nth-of-type(2) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(10) > div > div:nth-of-type(5) > div:nth-of-type(2) > label:nth-of-type(2)")
        addValueToDatePickerInput(true,"html > body > div:nth-of-type(1) > div > div:nth-of-type(2) > div > div:nth-of-type(2) > main > div:nth-of-type(3) > div > div > div:nth-of-type(1) > div > div > div > div:nth-of-type(2) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(10) > div > div:nth-of-type(5) > div:nth-of-type(2) > div > div:nth-of-type(1) > div",videoInfo.datetime)
        // åœ¨ä¸»çº¿ç¨‹ä¸­è®¾ç½®å»¶è¿Ÿæ‰§è¡Œ
        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 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()
    }
}
δÃüÃû
Binary files differ