From 1272c91430a0d0d3e283ba57b517bc16cef31017 Mon Sep 17 00:00:00 2001 From: lunaticbum Date: Fri, 1 Aug 2025 18:36:16 +0900 Subject: [PATCH] ... --- app/build.gradle.kts | 4 +- .../my_extension/docker-compose.yml | 13 + .../assets/extensions/my_extension/local.ini | 0 .../extensions/my_extension/messaging.js | 877 +++++++++++------- app/src/main/java/android/print/PDFPrint.java | 336 +++---- .../bums/lunatic/launcher/LauncherActivity.kt | 8 +- .../launcher/helpers/BluetoothManager.kt | 6 +- .../launcher/home/CustomVideoNodeRenderer.kt | 30 + .../bums/lunatic/launcher/home/GeckoWeb.kt | 177 +++- .../bums/lunatic/launcher/home/RssHome.kt | 17 +- .../launcher/home/adapters/RssItemAdapter.kt | 100 +- .../lunatic/launcher/workers/ArcaGetter.kt | 98 +- .../lunatic/launcher/workers/WorkersDb.kt | 45 +- app/src/main/res/layout/launcher_home.xml | 14 + .../main/res/layout/text_inpu_password.xml | 2 +- 15 files changed, 1051 insertions(+), 676 deletions(-) create mode 100644 app/src/main/assets/extensions/my_extension/docker-compose.yml create mode 100644 app/src/main/assets/extensions/my_extension/local.ini create mode 100644 app/src/main/kotlin/bums/lunatic/launcher/home/CustomVideoNodeRenderer.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c1f91334..3d504cb6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -115,8 +115,8 @@ dependencies { // implementation("org.mozilla.geckoview:geckoview:139.0.20250523173407") // https://mvnrepository.com/artifact/org.mozilla.geckoview/geckoview implementation("org.mozilla.geckoview:geckoview:139.0.20250523173407") - - + implementation("com.vladsch.flexmark:flexmark-all:0.64.0") +// implementation 'com.vladsch.flexmark:flexmark-all:0.64.8' // implementation("org.opencv:opencv-android:4.11.0") diff --git a/app/src/main/assets/extensions/my_extension/docker-compose.yml b/app/src/main/assets/extensions/my_extension/docker-compose.yml new file mode 100644 index 00000000..9eb34d07 --- /dev/null +++ b/app/src/main/assets/extensions/my_extension/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' +services: + couchdb: + image: couchdb:latest + container_name: couchdb + restart: always + ports: + - "5984:5984" # 외부접근: 5984포트 + environment: + - COUCHDB_USER=obsidian + - COUCHDB_PASSWORD=HiVi88131921 + volumes: + - ./data:/opt/couchdb/data diff --git a/app/src/main/assets/extensions/my_extension/local.ini b/app/src/main/assets/extensions/my_extension/local.ini new file mode 100644 index 00000000..e69de29b diff --git a/app/src/main/assets/extensions/my_extension/messaging.js b/app/src/main/assets/extensions/my_extension/messaging.js index ec87b460..5760942a 100644 --- a/app/src/main/assets/extensions/my_extension/messaging.js +++ b/app/src/main/assets/extensions/my_extension/messaging.js @@ -74,13 +74,7 @@ port.onMessage.addListener(response => { } break; case "saveContent":{ - sendMessage( - { - type: "SHOWVIEWER", - contents : document.documentElement.outerHTML - } - ); - + scrollToLazyImg() } default: port.postMessage(`Received: ${JSON.stringify(response)}`); @@ -121,11 +115,6 @@ if(document.querySelector("#html_encoder_div")) { } ); } -// else { -// sendMessage({type:"MSG",msg:"connected has Nothings"}); -// loadComplete() -// } - function getList(children) { // port.postMessage("Start of getList!" + children); @@ -213,7 +202,7 @@ function scrollByPercent(current , max) { const moveAmount = pageHeight / max; window.scrollTo({ top: moveAmount * current, behavior: "smooth" }); } -document.querySelector(".header__inner") + function scrollByPercentUpDown(isToDown , max) { const pageHeight = Math.max( document.body.scrollHeight, @@ -227,364 +216,68 @@ function scrollByPercentUpDown(isToDown , max) { const moveAmount = Math.max(pageHeight / max,150); window.scrollTo({ top: currentScroll + (moveAmount * isToDown) , behavior: "smooth" }); } - function loadComplete() { // try {port.postMessage(JSON.stringify({type: "NotRegistered"}));}catch (e) {} } function sendMessage(msg) { port.postMessage(JSON.stringify(msg)); } - function toast(msg) { port.postMessage(JSON.stringify({type:"MSG",msg:msg})); } -var time1 = null + +var mainContentsEl = null if (port) { - sendMessage({type: "MSG", msg:"connect prot"}); + sendMessage({type: "MSG", msg: "connect prot"}); + time1 = setTimeout(autoScrollAndSave(false), 2000) +} +function scrollToLazyImg() { + (function(autoScrollAndSave){ + // 한 번에 이동할 픽셀 + const step = 200; + // 반복 간격(ms) (느릴수록 로딩에 더 여유 생김) + const delay = 600; + // 스크롤 현재 위치 추적 + let currentY = window.scrollY; + let maxY = Math.max( + document.body.scrollHeight, + document.documentElement.scrollHeight + ); - - time1 = setTimeout( - - - function(){ - if (location.hostname.search("clien") > -1 && document.querySelectorAll('[class^="view_top"]')) { - document.querySelectorAll('[class^="view_top"]').forEach(e => e.remove()) - } - - if (location.hostname.search("toki") > -1 && document.querySelectorAll('[id^="id_mbv"]')) { - document.querySelectorAll('[id^="id_mbv"]').forEach(e => e.remove()) - } - if (location.hostname.search("toki") > -1 && document.querySelectorAll('[class^="basic-banner"]')) { - document.querySelectorAll('[class^="basic-banner"]').forEach(e => e.remove()) - } - if (document.querySelector(".top_google_ad_space")) { - document.querySelector(".top_google_ad_space").remove() - } - if (document.querySelectorAll(".adv-group")) { - document.querySelectorAll(".adv-group").forEach(e => - e.remove() - ) - } - if (document.querySelectorAll('[id^="div-gpt-ad"]')) { - document.querySelectorAll('[id^="div-gpt-ad"]').forEach(e => - e.remove() - ) - } - if (document.location.href.search("reddit") > -1) { - if (document.querySelector('#xpromo-bottom-sheet')) { - document.querySelector('#xpromo-bottom-sheet').remove() - } - } - if (document.querySelectorAll('[id^="div_adnmore_area"]')) { - document.querySelectorAll('[id^="div_adnmore_area"]').forEach(e => - e.remove() - ) - } - if (document.querySelectorAll('[id^="div_adnmore_area"]')) { - document.querySelectorAll('[id^="div_adnmore_area"]').forEach(e => - e.remove() - ) - } - if (document.querySelectorAll('[class^="adv-groupno"]')) { - document.querySelectorAll('[class^="adv-groupno"]').forEach(e => - e.remove() - ) - } - if (document.querySelectorAll('[class^="code-block"]')) { - document.querySelectorAll('[class^="code-block"]').forEach(e => e.remove()) - } - if (document.querySelectorAll('.ad-template')) { - document.querySelectorAll('.ad-template').forEach(function (e) { - e.remove() - }) - } - if (document.querySelectorAll('[class^="popupBanner_w popupOpen"]')) { - document.querySelectorAll('[class^="popupBanner_w popupOpen"]').forEach(function (e) { - e.remove() - }) - } - - if (document.querySelectorAll('iframe')) { - document.querySelectorAll('iframe').forEach(function (e) { - if (e.getAttribute("src") != null && (e.getAttribute("src").search("ads") > -1 || e.getAttribute("src").search("coupang") > -1)) { - e.remove() + function scrollStep() { + // 페이지 최대값(일정 margin 여유) + maxY = Math.max( + document.body.scrollHeight, + document.documentElement.scrollHeight + ); + if (currentY + step < maxY - window.innerHeight) { + currentY += step; + window.scrollTo({ top: currentY, behavior: 'smooth' }); + setTimeout(scrollStep, delay); + } else { + // 끝까지 도달하면 마지막으로 최하단 이동 + window.scrollTo({ top: maxY, behavior: 'smooth' }); + setTimeout(function() { + // == 여기에 저장 등 후처리 콜백 코드 호출 == + if (typeof autoScrollAndSave === 'function') { + autoScrollAndSave(true); + } else { + // 직접 메시지 보내거나, 원하는 최종 동작 실행 + // 예: window.postMessage('saveToObsidian', '*'); } - }) + }, 800); } - if (location.href.search("x.com") > -1) { - var mainClass = document.querySelector('section').className - - document.querySelector('section').querySelectorAll('div[class="'+ mainClass +'"]').forEach(function (e) { - if (e.hasAttribute("data-testid") && e.querySelector('video')) { - e.querySelectorAll('[poster]').forEach(function (e) { - - }) - console.log(e.innerHTML) - } - }) - - } - - if (document.querySelectorAll('[data-banner^="coupang-"]')) { - document.querySelectorAll('[data-banner^="coupang-"]').forEach(e => e.remove()) - } - - if (document.querySelectorAll('[id^="mobonDivBanner"]')) { - document.querySelectorAll('[id^="mobonDivBanner"]').forEach(e => e.remove()) - } - if (document.querySelectorAll('[id^="pnlTopAd"]')) { - document.querySelectorAll('[id^="pnlTopAd"]').forEach(e => e.remove()) - } - if (document.querySelectorAll('[class^="ad-tag"]')) { - document.querySelectorAll('[class^="ad-tag"]').forEach(e => e.remove()) - } - if (document.querySelectorAll('[class^="science-banner-area"]')) { - document.querySelectorAll('[class^="science-banner-area"]').forEach(e=> e.remove()) - } - if (location.href.search("torrentzota") > -1 && document.querySelectorAll('a')) { - document.querySelectorAll('a').forEach(function (e) { - if (e.getAttribute('href') != null && e.getAttribute('href').startsWith("/adver-")) { - e.remove() - } - } - ) - if(document.querySelectorAll('[class^="py-4 flex flex-row border-b topic-item"]').length > 1) { - var datas = [] - document.querySelectorAll('[class^="py-4 flex flex-row border-b topic-item"]').forEach(function (e) { - var title = "" - var link = "" - e.querySelectorAll("a").forEach(function (e){ - if(e.getAttribute("class") === "item-link"){ - title = e.getAttribute('title') - } - if(e.getAttribute("class") === "item-link"){ - link = e.getAttribute('href') - if (link.length > 0) { - link = location.protocol + '//' + location.hostname + link - } - } - }) - var description = e.querySelector('.flex-none w-16 text-center').textContent + e.querySelector('.badge badge-third w-auto px-1 flex-none mr-2 float-left').textContent - var md = e.querySelector(".flex-none w-14 text-center hidden md:block").textContent - - let todayYear = new Date().getFullYear(); - let now = new Date(); - let hh = String(now.getHours()).padStart(2, '0'); // 시 (2자리) - let mm = String(now.getMinutes()).padStart(2, '0'); // 분 (2자리) - let ss = String(now.getSeconds()).padStart(2, '0'); // 초 (2자리) - - let time = `${hh}:${mm}:${ss}`; - let combinedStr = todayYear + "-" + md + " " + time; - let dateObj = new Date(combinedStr); - - datas.push({ - "title" : title, - "description" : description, - "originPage" : link, - "pubDate" : dateObj.getTime(), - "category" : "TORRENT" - }); - }) - if(datas.length > 0) { - sendMessage( - { - type: "PRIVATES", - privates: datas, - currentPage : location.href - } - ); - } - } - if (document.querySelectorAll('[class^="w-full flex"]').length > 1) { - var datas = [] - document.querySelectorAll('[class^="w-full flex"]').forEach(function (e) { - var thumbnail = "" - e.querySelectorAll("img").forEach(function (e){ - if(e.getAttribute("class") === "border"){ - thumbnail = e.getAttribute('src') - } - }) - - var title = "" - var link = "" - e.querySelectorAll("a").forEach(function (e){ - if(e.getAttribute("class") === "item-link"){ - title = e.getAttribute('title') - } - if(e.getAttribute("class") === "item-link"){ - link = e.getAttribute('href') - if (link.length > 0) { - link = location.protocol + '//' + location.hostname + link - } - } - }) - - - var description = "" - var time = "" - var md = "" - if(e.querySelector('[class^="pb-2 w-100 text-gray-500"]')){ - description = e.querySelector('[class^="pb-2 w-100 text-gray-500"]').textContent.replace(/\s+/g, ' ').trim(); - md = description.split(" ")[1].trim(); - time = description.split(" ")[2].trim(); - description = description.split(" ")[0].trim(); - } - console.log(link) - console.log(thumbnail) - console.log(title) - console.log(description) - console.log(md) - console.log(time) - - - - let todayYear = new Date().getFullYear(); - let combinedStr = todayYear + "-" + md + " " + time; - let dateObj = new Date(combinedStr); - - datas.push({ - "title" : title, - "description" : description, - "originPage" : link, - "thumbnail" : thumbnail, - "pubDate" : dateObj.getTime(), - "category" : "TORRENT" - }); - }) - if(datas.length > 0) { - sendMessage( - { - type: "PRIVATES", - privates: datas, - currentPage : location.href - } - ); - } - - } - - } - - if (document.querySelectorAll('[class^="col-md-4 mb-4 video-item"]').length > 1) { - var datas = [] - document.querySelectorAll('[class^="col-md-4 mb-4 video-item"]').forEach(function (e) { - var date = 0 - try { - const dateString = e.querySelector('[class^="mb-2"]').querySelector("a").textContent.trim(); - - const [day, month, year] = dateString.split("/").map(Number); - date = new Date(year, month - 1, day).getTime(); - }catch (e) { - - } - var actor = "" - try { - actor = e.querySelector('[class^="mb-1"]').getAttribute("alt").trim() - }catch (e) { - - } - var desc = "" - try { - e.querySelectorAll('[class^="badge badge-"]').forEach(function (e) { - try { - if (Number(e.textContent) > 0) { - - }else { - if (desc.length > 0) { - desc += "," - } - desc += e.textContent.trim() - } - }catch (e) {} - } - ) - }catch (e) { - - } - var thumb = "" - try { - thumb = e.querySelector("td").querySelector("a").getAttribute('data-link') - try { - var sets = e.querySelector("td").querySelector("img").getAttribute('srcset') - if(sets.search(",") > -1) { - var srcSet = sets.split(",") - var newT = srcSet[srcSet.length - 1] - if (newT != null && newT.length > 5) { - thumb = newT - } - } - } catch (e) {} - }catch (e) {} - var magnet = "" - try { - e.querySelectorAll("td").forEach(function (e) { - e.querySelectorAll("a").forEach(function (e) { - if(e.getAttribute("href").startsWith("magnet")) { - magnet = e.getAttribute("href").replaceAll("&", "&"); - } - }) - }) - }catch (e) { - - } - - var title = ""; - try { - e.querySelector(".name").querySelector("a").querySelectorAll("span").forEach(function (e) { - if (e.hasAttribute("class") == false) { - title = e.textContent.trim(); - } - }) - }catch (e) { - - } - var originPage = "" - try { - originPage = location.protocol + "//" + location.hostname + e.querySelector(".name").querySelector("a").getAttribute("href"); - }catch (e) { - - } - var screenshots = "" - try { - e.querySelectorAll("a").forEach(function (e) { - if(e.getAttribute("href").search("screenshots") > -1) { - screenshots = e.getAttribute("href"); - } - }) - }catch (e) { - - } - if (thumb.length > 0 || screenshots.length > 0) {} - datas.push({ - "title" : title, - "description" : desc, - "originPage" : originPage, - "magnet_link" : magnet, - "thumbnail" : thumb, - "pubDate" : date, - "screenshotsUrl" : screenshots, - "chosung" : "", - "category" : "PRIVATE" - }); - }) - sendMessage( - { - type: "PRIVATES", - privates: datas, - currentPage : location.href - } - ); - - gotoNext() - } - },1500) - + } + // 시작(로드 이벤트 이후 실행 권장) + scrollStep(); + })(autoScrollAndSave); } var targetUrl = "" var time2 = null +var time1 = null function gotoNext() { clearTimeout(time1) try{ @@ -614,4 +307,484 @@ function gotoNext() { } catch (e) { } +} + +function isNewerThanOneDay(dateStr) { + if (!dateStr) return false; + const date = new Date(dateStr); + if (isNaN(date)) return false; + + const now = new Date(); + const oneDayMs = 24 * 60 * 60 * 1000; + return (now - date) < oneDayMs; +} +function autoScrollAndSave(senContents) { + if (location.hostname.search("theqoo.net") > -1 && document.querySelectorAll('[class^="m-list m-element"]')) { + document.querySelectorAll('[class^="m-list m-element"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="button_area"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="board_content_google_ad"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="clearfix list-header"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="clearfix list-footer"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="main-footer"]').forEach(e => e.remove()) + document.querySelectorAll('ins[class^="adsbygoogle"]').forEach(e => e.remove()) + mainContentsEl = document.querySelector('div[id="grid-content"]') + } + + if (location.hostname.search("dcinside.com") > -1 && document.querySelectorAll('[class^="container"]')) { + document.querySelectorAll('[id^="view_btn_area"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="trend-rank"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="view-btm-con"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="md-tit-box"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="gall-detail-lst"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="outside-search-box"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="footer ftlong"]').forEach(e => e.remove()) + mainContentsEl = document.querySelector('div[class="container"]') + } + + if (location.hostname.search("fmkorea.com") > -1 && document.querySelectorAll('[class^="bd bd_mobile"]')) { + document.querySelectorAll('[class^="fmad_wrapper fmad_naver_power_link"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="ad ad_wrapper"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="bd_lst_wrp"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="m_top_hotdeal"]').forEach(e => e.remove()) + mainContentsEl = document.querySelector('div[class="bd bd_mobile"]') + } + + if (location.hostname.search("acrofan.com") > -1 && document.querySelectorAll('[id^="wide"]')) { + document.querySelectorAll('[class^="header"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="footer"]').forEach(e => e.remove()) + document.querySelectorAll('[id^="tabmenu"]').forEach(e => e.remove()) + mainContentsEl = document.querySelector('div[class="wide"]') + } + + if (location.hostname.search("yna.co.kr") > -1 && document.querySelectorAll('[class^="wrapper"]')) { + document.querySelectorAll('[class^="aside-box426 sticky"]').forEach(e => e.remove()) + document.querySelectorAll('aside[class^="aside-box"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="section02"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="content03 wide"]').forEach(e => e.remove()) + document.querySelectorAll('[id="footer"]').forEach(e => e.remove()) + mainContentsEl = document.querySelector('div[id="container"]') + } + + if (location.hostname.search("clien") > -1 && document.querySelectorAll('[class^="content_view"]')) { + document.querySelectorAll('[class^="view_top"]').forEach(e => e.remove()) + document.querySelectorAll('[id^="naverAd"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="content_view_list"]').forEach(e => e.remove()) + document.querySelectorAll('[class^="footer_wrap"]').forEach(e => e.remove()) + mainContentsEl = document.querySelector('div[id="content_view"]') + } + + if (location.hostname.search("toki") > -1 && document.querySelectorAll('[id^="id_mbv"]')) { + document.querySelectorAll('[id^="id_mbv"]').forEach(e => e.remove()) + } + if (location.hostname.search("toki") > -1 && document.querySelectorAll('[class^="basic-banner"]')) { + document.querySelectorAll('[class^="basic-banner"]').forEach(e => e.remove()) + } + if (document.querySelector(".top_google_ad_space")) { + document.querySelector(".top_google_ad_space").remove() + } + if (document.querySelectorAll(".adv-group")) { + document.querySelectorAll(".adv-group").forEach(e => + e.remove() + ) + } + if (document.querySelectorAll('[id^="div-gpt-ad"]')) { + document.querySelectorAll('[id^="div-gpt-ad"]').forEach(e => + e.remove() + ) + } + if (document.location.href.search("reddit") > -1) { + if (document.querySelector('#xpromo-bottom-sheet')) { + document.querySelector('#xpromo-bottom-sheet').remove() + } + } + if (document.querySelectorAll('[id^="div_adnmore_area"]')) { + document.querySelectorAll('[id^="div_adnmore_area"]').forEach(e => + e.remove() + ) + } + if (document.querySelectorAll('[id^="div_adnmore_area"]')) { + document.querySelectorAll('[id^="div_adnmore_area"]').forEach(e => + e.remove() + ) + } + if (document.querySelectorAll('[class^="adv-groupno"]')) { + document.querySelectorAll('[class^="adv-groupno"]').forEach(e => + e.remove() + ) + } + if (document.querySelectorAll('[class^="code-block"]')) { + document.querySelectorAll('[class^="code-block"]').forEach(e => e.remove()) + } + if (document.querySelectorAll('.ad-template')) { + document.querySelectorAll('.ad-template').forEach(function (e) { + e.remove() + }) + } + if (location.href.search("arca.live") > -1 && document.querySelectorAll('[class^="vrow hybrid"]')) { + const tempArray = []; + document.querySelectorAll('[class^="vrow hybrid"]').forEach(function (aracaLi) { + if (aracaLi.innerHTML.search("title ") > -1) { + // title.hybrid-title 클래스가 붙은 첫 번째 요소 텍스트 추출 + let titleEl = aracaLi.querySelector('.title.hybrid-title'); + let title = titleEl ? titleEl.textContent.trim() : ''; + + // badge 클래스 텍스트와 user-info 클래스 텍스트 합치기 + let descBadge = aracaLi.querySelector('.badge'); + let descUserInfo = aracaLi.querySelector('.user-info'); + let desc = (descBadge ? descBadge.textContent.trim() : '') + if (desc.length > 0) { + desc = desc + "," + } + desc = desc + (descUserInfo ? descUserInfo.textContent.trim() : ''); + if (descUserInfo) { + desc = desc + "," + } + + // time 태그 datetime 속성 값 + let timeEl = aracaLi.querySelector('time'); + + let dateTime = timeEl ? timeEl.getAttribute('datetime') : ''; + // console.log("dateTime >>> "+ dateTime) + // const dateObj = new Date(dateTime); + // console.log(dateObj.getFullYear()); // 2025 + // console.log(dateObj.getMonth() + 1); // 7 (월은 0부터 시작하므로 +1) + // console.log(dateObj.getDate()); // 30 + // console.log(dateObj.getHours()); // 13 (현지 시간 기준) + // console.log(dateObj.getMinutes()); // 45 + // console.log(dateObj.getSeconds()); + // console.log(dateObj); + // img 태그 src 값 + let imgEl = aracaLi.querySelector('img'); + let thumbnail = imgEl ? imgEl.getAttribute('src') : ''; + + // 링크 만들기 + let link = 'https://arca.live'; + if (titleEl && titleEl.getAttribute('href')) { + link += titleEl.getAttribute('href'); + } else { + let aEl = aracaLi.querySelector('a'); + if (aEl && aEl.getAttribute('href')) { + link += aEl.getAttribute('href'); + } + } + + if (title.length > 0 && link.length > 20) { + // thumbnail 절대경로 처리 (프로토콜이 없는 경우 https: 붙이기) + if (thumbnail.startsWith('//')) { + thumbnail = 'https:' + thumbnail; + } + + // 날짜가 하루 이내인지 확인하는 함수 사용 + + tempArray.push({ + title: title.replace(/\s+/g, ' ').trim(), + description: desc.replace(/\s+/g, ' ').trim() + "ARCA", + pubDate: new Date(dateTime).getTime(), + originPage: link, + "category": "ARCA", + thumbnail: thumbnail + }); + + } + } + + }) + if (tempArray.length > 0) { + console.log(tempArray); + sendMessage( + { + type: "PRIVATES", + privates: tempArray, + currentPage: location.href + } + ); + location.href = "about:blank;" + } + } + if (document.querySelectorAll('[class^="popupBanner_w popupOpen"]')) { + document.querySelectorAll('[class^="popupBanner_w popupOpen"]').forEach(function (e) { + e.remove() + }) + } + + if (document.querySelectorAll('iframe')) { + document.querySelectorAll('iframe').forEach(function (e) { + if (e.getAttribute("src") != null && (e.getAttribute("src").search("ads") > -1 || e.getAttribute("src").search("coupang") > -1)) { + e.remove() + } + }) + } + if (location.href.search("x.com") > -1) { + var mainClass = document.querySelector('section').className + + document.querySelector('section').querySelectorAll('div[class="' + mainClass + '"]').forEach(function (e) { + if (e.hasAttribute("data-testid") && e.querySelector('video')) { + e.querySelectorAll('[poster]').forEach(function (e) { + + }) + console.log(e.innerHTML) + } + }) + + } + + if (document.querySelectorAll('[data-banner^="coupang-"]')) { + document.querySelectorAll('[data-banner^="coupang-"]').forEach(e => e.remove()) + } + + if (document.querySelectorAll('[id^="mobonDivBanner"]')) { + document.querySelectorAll('[id^="mobonDivBanner"]').forEach(e => e.remove()) + } + if (document.querySelectorAll('[id^="pnlTopAd"]')) { + document.querySelectorAll('[id^="pnlTopAd"]').forEach(e => e.remove()) + } + if (document.querySelectorAll('[class^="ad-tag"]')) { + document.querySelectorAll('[class^="ad-tag"]').forEach(e => e.remove()) + } + if (document.querySelectorAll('[class^="science-banner-area"]')) { + document.querySelectorAll('[class^="science-banner-area"]').forEach(e => e.remove()) + } + if (location.href.search("torrentzota") > -1 && document.querySelectorAll('a')) { + document.querySelectorAll('a').forEach(function (e) { + if (e.getAttribute('href') != null && e.getAttribute('href').startsWith("/adver-")) { + e.remove() + } + } + ) + if (document.querySelectorAll('[class^="py-4 flex flex-row border-b topic-item"]').length > 1) { + var datas = [] + document.querySelectorAll('[class^="py-4 flex flex-row border-b topic-item"]').forEach(function (e) { + var title = "" + var link = "" + e.querySelectorAll("a").forEach(function (e) { + if (e.getAttribute("class") === "item-link") { + title = e.getAttribute('title') + } + if (e.getAttribute("class") === "item-link") { + link = e.getAttribute('href') + if (link.length > 0) { + link = location.protocol + '//' + location.hostname + link + } + } + }) + var description = e.querySelector('.flex-none w-16 text-center').textContent + e.querySelector('.badge badge-third w-auto px-1 flex-none mr-2 float-left').textContent + var md = e.querySelector(".flex-none w-14 text-center hidden md:block").textContent + + let todayYear = new Date().getFullYear(); + let now = new Date(); + let hh = String(now.getHours()).padStart(2, '0'); // 시 (2자리) + let mm = String(now.getMinutes()).padStart(2, '0'); // 분 (2자리) + let ss = String(now.getSeconds()).padStart(2, '0'); // 초 (2자리) + + let time = `${hh}:${mm}:${ss}`; + let combinedStr = todayYear + "-" + md + " " + time; + let dateObj = new Date(combinedStr); + + datas.push({ + "title": title, + "description": description, + "originPage": link, + "pubDate": dateObj.getTime(), + "category": "TORRENT" + }); + }) + if (datas.length > 0) { + sendMessage( + { + type: "PRIVATES", + privates: datas, + currentPage: location.href + } + ); + } + } + if (document.querySelectorAll('[class^="w-full flex"]').length > 1) { + var datas = [] + document.querySelectorAll('[class^="w-full flex"]').forEach(function (e) { + var thumbnail = "" + e.querySelectorAll("img").forEach(function (e) { + if (e.getAttribute("class") === "border") { + thumbnail = e.getAttribute('src') + } + }) + + var title = "" + var link = "" + e.querySelectorAll("a").forEach(function (e) { + if (e.getAttribute("class") === "item-link") { + title = e.getAttribute('title') + } + if (e.getAttribute("class") === "item-link") { + link = e.getAttribute('href') + if (link.length > 0) { + link = location.protocol + '//' + location.hostname + link + } + } + }) + + + var description = "" + var time = "" + var md = "" + if (e.querySelector('[class^="pb-2 w-100 text-gray-500"]')) { + description = e.querySelector('[class^="pb-2 w-100 text-gray-500"]').textContent.replace(/\s+/g, ' ').trim(); + md = description.split(" ")[1].trim(); + time = description.split(" ")[2].trim(); + description = description.split(" ")[0].trim(); + } + console.log(link) + console.log(thumbnail) + console.log(title) + console.log(description) + console.log(md) + console.log(time) + + + let todayYear = new Date().getFullYear(); + let combinedStr = todayYear + "-" + md + " " + time; + let dateObj = new Date(combinedStr); + + datas.push({ + "title": title, + "description": description, + "originPage": link, + "thumbnail": thumbnail, + "pubDate": dateObj.getTime(), + "category": "TORRENT" + }); + }) + if (datas.length > 0) { + sendMessage( + { + type: "PRIVATES", + privates: datas, + currentPage: location.href + } + ); + } + + } + + } + + if (document.querySelectorAll('[class^="col-md-4 mb-4 video-item"]').length > 1) { + var datas = [] + document.querySelectorAll('[class^="col-md-4 mb-4 video-item"]').forEach(function (e) { + var date = 0 + try { + const dateString = e.querySelector('[class^="mb-2"]').querySelector("a").textContent.trim(); + + const [day, month, year] = dateString.split("/").map(Number); + date = new Date(year, month - 1, day).getTime(); + } catch (e) { + + } + var actor = "" + try { + actor = e.querySelector('[class^="mb-1"]').getAttribute("alt").trim() + } catch (e) { + + } + var desc = "" + try { + e.querySelectorAll('[class^="badge badge-"]').forEach(function (e) { + try { + if (Number(e.textContent) > 0) { + + } else { + if (desc.length > 0) { + desc += "," + } + desc += e.textContent.trim() + } + } catch (e) { + } + } + ) + } catch (e) { + + } + var thumb = "" + try { + thumb = e.querySelector("td").querySelector("a").getAttribute('data-link') + try { + var sets = e.querySelector("td").querySelector("img").getAttribute('srcset') + if (sets.search(",") > -1) { + var srcSet = sets.split(",") + var newT = srcSet[srcSet.length - 1] + if (newT != null && newT.length > 5) { + thumb = newT + } + } + } catch (e) { + } + } catch (e) { + } + var magnet = "" + try { + e.querySelectorAll("td").forEach(function (e) { + e.querySelectorAll("a").forEach(function (e) { + if (e.getAttribute("href").startsWith("magnet")) { + magnet = e.getAttribute("href").replaceAll("&", "&"); + } + }) + }) + } catch (e) { + + } + + var title = ""; + try { + e.querySelector(".name").querySelector("a").querySelectorAll("span").forEach(function (e) { + if (e.hasAttribute("class") == false) { + title = e.textContent.trim(); + } + }) + } catch (e) { + + } + var originPage = "" + try { + originPage = location.protocol + "//" + location.hostname + e.querySelector(".name").querySelector("a").getAttribute("href"); + } catch (e) { + + } + var screenshots = "" + try { + e.querySelectorAll("a").forEach(function (e) { + if (e.getAttribute("href").search("screenshots") > -1) { + screenshots = e.getAttribute("href"); + } + }) + } catch (e) { + + } + if (thumb.length > 0 || screenshots.length > 0) { + } + datas.push({ + "title": title, + "description": desc, + "originPage": originPage, + "magnet_link": magnet, + "thumbnail": thumb, + "pubDate": date, + "screenshotsUrl": screenshots, + "chosung": "", + "category": "PRIVATE" + }); + }) + sendMessage( + { + type: "PRIVATES", + privates: datas, + currentPage: location.href + } + ); + + gotoNext() + } + window.scrollTo({ top: 10, behavior: 'smooth' }); + if (senContents) { + sendMessage({type: "MainContentsEl", contents: mainContentsEl.outerHTML, currentPage: location.href}); + } } \ No newline at end of file diff --git a/app/src/main/java/android/print/PDFPrint.java b/app/src/main/java/android/print/PDFPrint.java index 7500e8c6..68c84fe6 100644 --- a/app/src/main/java/android/print/PDFPrint.java +++ b/app/src/main/java/android/print/PDFPrint.java @@ -1,168 +1,168 @@ -//package android.print; -// -//import android.app.Activity; -//import android.content.Context; -//import android.os.Bundle; -//import android.os.CancellationSignal; -//import android.os.ParcelFileDescriptor; -//import android.webkit.WebView; -//import android.webkit.WebViewClient; -// -//import java.io.File; -//import java.io.FileInputStream; -//import java.io.FileOutputStream; -//import java.io.IOException; -//import java.io.InputStream; -//import java.io.OutputStream; -// -//public class PDFPrint { -// -// public static void generatePDFFromHTML(final Context context, final File file, final String htmlString, final OnPDFPrintListener onPDFPrintListener) { -// final WebView mWebView = new WebView(context); -// mWebView.setWebViewClient(new WebViewClient() { -// @Override -// public void onPageFinished(WebView view, String url) { -// PrintAttributes printAttributes = new PrintAttributes.Builder() -// .setMediaSize(PrintAttributes.MediaSize.ISO_A4) -// .setResolution(new PrintAttributes.Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600)) -// .setMinMargins(PrintAttributes.Margins.NO_MARGINS) -// .build(); -// -// final PrintDocumentAdapter documentAdapter = mWebView.createPrintDocumentAdapter(file.getName()); -// documentAdapter.onLayout(null, printAttributes, null, new PrintDocumentAdapter.LayoutResultCallback() { -// @Override -// public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { -// documentAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(file), null, new PrintDocumentAdapter.WriteResultCallback() { -// -// @Override -// public void onWriteCancelled() { -// super.onWriteCancelled(); -// onPDFPrintListener.onError(new Exception("PDF Write cancelled.")); -// } -// -// @Override -// public void onWriteFailed(CharSequence error) { -// super.onWriteFailed(error); -// onPDFPrintListener.onError(new Exception(error.toString())); -// } -// -// @Override -// public void onWriteFinished(PageRange[] pages) { -// super.onWriteFinished(pages); -// onPDFPrintListener.onSuccess(file); -// } -// }); -// } -// }, null); -// } -// }); -// mWebView.loadData(htmlString.replaceAll("#", "%23"), "text/HTML", "UTF-8"); -// } -// -// public static void generatePDFFromWebView(final File file, final WebView webView, final OnPDFPrintListener onPDFPrintListener) { -// PrintAttributes printAttributes = new PrintAttributes.Builder() -// .setMediaSize(PrintAttributes.MediaSize.ISO_A4) -// .setResolution(new PrintAttributes.Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600)) -// .setMinMargins(PrintAttributes.Margins.NO_MARGINS) -// .build(); -// -// final PrintDocumentAdapter documentAdapter = webView.createPrintDocumentAdapter(file.getName()); -// documentAdapter.onLayout(null, printAttributes, null, new PrintDocumentAdapter.LayoutResultCallback() { -// @Override -// public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { -// documentAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(file), null, new PrintDocumentAdapter.WriteResultCallback() { -// -// @Override -// public void onWriteCancelled() { -// super.onWriteCancelled(); -// onPDFPrintListener.onError(new Exception("PDF Write cancelled.")); -// } -// -// @Override -// public void onWriteFailed(CharSequence error) { -// super.onWriteFailed(error); -// try { -// if (error != null && error.toString().length() > 0) { -// onPDFPrintListener.onError(new Exception(error.toString())); -// } else { -// onPDFPrintListener.onError(new Exception("Empty Page")); -// } -// }catch (Exception e) {e.printStackTrace();} -// } -// -// @Override -// public void onWriteFinished(PageRange[] pages) { -// super.onWriteFinished(pages); -// onPDFPrintListener.onSuccess(file); -// } -// }); -// } -// }, null); -// } -// -// private static ParcelFileDescriptor getOutputFile(File file) { -// try { -// if (!file.exists()) { -// file.createNewFile(); -// } -// return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// return null; -// } -// -// public static PrintJob printPDF(final Activity activity, final File pdfFileToPrint, final PrintAttributes printAttributes) { -// PrintManager printManager = (PrintManager) activity.getSystemService(Context.PRINT_SERVICE); -// String jobName = Long.valueOf(System.currentTimeMillis()).toString(); -// return printManager.print(jobName, new PrintDocumentAdapter() { -// @Override -// public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback) { -// InputStream input = null; -// OutputStream output = null; -// -// try { -// -// input = new FileInputStream(pdfFileToPrint); -// output = new FileOutputStream(destination.getFileDescriptor()); -// -// byte[] buf = new byte[1024]; -// int bytesRead; -// -// while ((bytesRead = input.read(buf)) > 0) { -// output.write(buf, 0, bytesRead); -// } -// -// callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES}); -// -// } catch (Exception e) { -// e.printStackTrace(); -// } finally { -// try { -// input.close(); -// output.close(); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// } -// } -// -// @Override -// public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) { -// if (cancellationSignal.isCanceled()) { -// callback.onLayoutCancelled(); -// return; -// } -// -// PrintDocumentInfo pdi = new PrintDocumentInfo.Builder(pdfFileToPrint.getName()).setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build(); -// callback.onLayoutFinished(pdi, true); -// } -// }, printAttributes); -// } -// -// public interface OnPDFPrintListener { -// void onSuccess(File file); -// -// void onError(Exception exception); -// } -//} \ No newline at end of file +package android.print; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.os.CancellationSignal; +import android.os.ParcelFileDescriptor; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class PDFPrint { + + public static void generatePDFFromHTML(final Context context, final File file, final String htmlString, final OnPDFPrintListener onPDFPrintListener) { + final WebView mWebView = new WebView(context); + mWebView.setWebViewClient(new WebViewClient() { + @Override + public void onPageFinished(WebView view, String url) { + PrintAttributes printAttributes = new PrintAttributes.Builder() + .setMediaSize(PrintAttributes.MediaSize.ISO_A4) + .setResolution(new PrintAttributes.Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600)) + .setMinMargins(PrintAttributes.Margins.NO_MARGINS) + .build(); + + final PrintDocumentAdapter documentAdapter = mWebView.createPrintDocumentAdapter(file.getName()); + documentAdapter.onLayout(null, printAttributes, null, new PrintDocumentAdapter.LayoutResultCallback() { + @Override + public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { + documentAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(file), null, new PrintDocumentAdapter.WriteResultCallback() { + + @Override + public void onWriteCancelled() { + super.onWriteCancelled(); + onPDFPrintListener.onError(new Exception("PDF Write cancelled.")); + } + + @Override + public void onWriteFailed(CharSequence error) { + super.onWriteFailed(error); + onPDFPrintListener.onError(new Exception(error.toString())); + } + + @Override + public void onWriteFinished(PageRange[] pages) { + super.onWriteFinished(pages); + onPDFPrintListener.onSuccess(file); + } + }); + } + }, null); + } + }); + mWebView.loadData(htmlString.replaceAll("#", "%23"), "text/HTML", "UTF-8"); + } + + public static void generatePDFFromWebView(final File file, final WebView webView, final OnPDFPrintListener onPDFPrintListener) { + PrintAttributes printAttributes = new PrintAttributes.Builder() + .setMediaSize(PrintAttributes.MediaSize.ISO_A4) + .setResolution(new PrintAttributes.Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600)) + .setMinMargins(PrintAttributes.Margins.NO_MARGINS) + .build(); + + final PrintDocumentAdapter documentAdapter = webView.createPrintDocumentAdapter(file.getName()); + documentAdapter.onLayout(null, printAttributes, null, new PrintDocumentAdapter.LayoutResultCallback() { + @Override + public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { + documentAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(file), null, new PrintDocumentAdapter.WriteResultCallback() { + + @Override + public void onWriteCancelled() { + super.onWriteCancelled(); + onPDFPrintListener.onError(new Exception("PDF Write cancelled.")); + } + + @Override + public void onWriteFailed(CharSequence error) { + super.onWriteFailed(error); + try { + if (error != null && error.toString().length() > 0) { + onPDFPrintListener.onError(new Exception(error.toString())); + } else { + onPDFPrintListener.onError(new Exception("Empty Page")); + } + }catch (Exception e) {e.printStackTrace();} + } + + @Override + public void onWriteFinished(PageRange[] pages) { + super.onWriteFinished(pages); + onPDFPrintListener.onSuccess(file); + } + }); + } + }, null); + } + + private static ParcelFileDescriptor getOutputFile(File file) { + try { + if (!file.exists()) { + file.createNewFile(); + } + return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static PrintJob printPDF(final Activity activity, final File pdfFileToPrint, final PrintAttributes printAttributes) { + PrintManager printManager = (PrintManager) activity.getSystemService(Context.PRINT_SERVICE); + String jobName = Long.valueOf(System.currentTimeMillis()).toString(); + return printManager.print(jobName, new PrintDocumentAdapter() { + @Override + public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback) { + InputStream input = null; + OutputStream output = null; + + try { + + input = new FileInputStream(pdfFileToPrint); + output = new FileOutputStream(destination.getFileDescriptor()); + + byte[] buf = new byte[1024]; + int bytesRead; + + while ((bytesRead = input.read(buf)) > 0) { + output.write(buf, 0, bytesRead); + } + + callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES}); + + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + input.close(); + output.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @Override + public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) { + if (cancellationSignal.isCanceled()) { + callback.onLayoutCancelled(); + return; + } + + PrintDocumentInfo pdi = new PrintDocumentInfo.Builder(pdfFileToPrint.getName()).setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build(); + callback.onLayoutFinished(pdi, true); + } + }, printAttributes); + } + + public interface OnPDFPrintListener { + void onSuccess(File file); + + void onError(Exception exception); + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt b/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt index 4465807f..f9137338 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt @@ -569,8 +569,11 @@ internal class LauncherActivity : CommonActivity() { private fun initGeckoRuntime() { if (sRuntime == null) { try { - sRuntime = GeckoRuntime.create(this, GeckoRuntimeSettings.Builder().extensionsProcessEnabled(true) - .extensionsWebAPIEnabled(true).experimentDelegate(experimentDelegate) + sRuntime = GeckoRuntime.create(this, GeckoRuntimeSettings.Builder() + .extensionsProcessEnabled(true) + .extensionsWebAPIEnabled(true) + .experimentDelegate(experimentDelegate) + .debugLogging(false) .remoteDebuggingEnabled(true).build()) } catch (e : Exception) { e.printStackTrace() @@ -717,6 +720,7 @@ internal class LauncherActivity : CommonActivity() { } val callBackHandler = Handler(Looper.getMainLooper()) + } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/helpers/BluetoothManager.kt b/app/src/main/kotlin/bums/lunatic/launcher/helpers/BluetoothManager.kt index d2d32723..fb2106cc 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/helpers/BluetoothManager.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/helpers/BluetoothManager.kt @@ -73,9 +73,9 @@ class BluetoothManager : Service() { val filter = IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED) registerReceiver(bluetoothreceiver, filter) refreshFeeds() -// GeckoWeb(applicationContext).apply { -// loadUrl("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=") -// } + GeckoWeb(applicationContext).apply { + loadUrl("https://arca.live/b/live") + } } override fun onBind(intent: Intent?): IBinder? { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/CustomVideoNodeRenderer.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/CustomVideoNodeRenderer.kt new file mode 100644 index 00000000..30fab4c3 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/CustomVideoNodeRenderer.kt @@ -0,0 +1,30 @@ +import com.vladsch.flexmark.html2md.converter.* +import com.vladsch.flexmark.util.data.DataHolder +import org.jsoup.nodes.Element + +class CustomVideoNodeRenderer(options: DataHolder?) : HtmlNodeRenderer { + + override fun getHtmlNodeRendererHandlers(): Set> { + return setOf( + HtmlNodeRendererHandler( + "video", // 처리할 태그명! + Element::class.java + ) { node, context, markdown -> + // node: org.jsoup.nodes.Element 타입, 즉