This commit is contained in:
lunaticbum 2025-08-21 17:20:03 +09:00
parent 2f63f8550a
commit 634d703572
16 changed files with 407 additions and 141 deletions

View File

@ -9,7 +9,7 @@
"name": "Sample Extension",
"background": {
"scripts": ["background.js"]
"scripts": ["Dotax.js", "background.js"]
},
"content_scripts": [
{

View File

@ -1,5 +1,55 @@
function pubDateNumber(tdateTime) {
let date = new Date();
let dateTime = date.getTime();
let before = 0;
try {
let targetDate = tdateTime || "";
if (targetDate.length > 1) {
let dateDesc = targetDate;
let isBefore = dateDesc.includes("전");
let dayString = dateDesc.replace(/[^0-9]/g, "");
before = parseInt(dayString);
if (dateDesc.includes("년")) {
before = 365 * before;
dateTime = isBefore ? this.beforeDayBy(date, before) : this.afterDay(date, before);
} else if (dateDesc.includes("월")) {
before = 30 * before;
dateTime = isBefore ? this.beforeDayBy(date, before) : this.afterDay(date, before);
} else if (dateDesc.includes("주")) {
before = 7 * before;
dateTime = isBefore ? this.beforeDayBy(date, before) : this.afterDay(date, before);
} else if (dateDesc.includes("일")) {
dateTime = isBefore ? this.beforeDayBy(date, before) : this.afterDay(date, before);
} else if (dateDesc.includes("시간")) {
dateTime = isBefore ? dateTime - before * 60 * 60 * 1000 : dateTime + before * 60 * 60 * 1000;
} else if (dateDesc.includes("분")) {
dateTime = isBefore ? dateTime - before * 60 * 1000 : dateTime + before * 60 * 1000;
} else if (dateDesc.includes("초")) {
dateTime = isBefore ? dateTime - before * 1000 : dateTime + before * 1000;
}
}
} catch (e) {
// 예외 무시
} finally {
}
return dateTime;
}
// Kotlin의 beforeDayBy 대응 - date에서 before일 전 타임스탬프 계산 함수
function beforeDayBy(date, before) {
return date.getTime() - before * 24 * 60 * 60 * 1000;
}
// Kotlin의 afterDay 대응 - date에서 before일 후 타임스탬프 계산 함수
function afterDay(date, before) {
return date.getTime() + before * 24 * 60 * 60 * 1000;
}
const port = browser.runtime.connectNative("browser");
port.onMessage.addListener(response => {
var type= response["type"];
@ -360,9 +410,9 @@ function autoScrollAndSave(senContents) {
}catch (e) { }
try {
// 공통 광고 요소 제거는 항상 실행
handleCommon();
}catch (e) { }
// 공통 광고 요소 제거는 항상 실행
handleCommon();
}catch (e) { }
if (mainContentsEl == null) {
mainContentsEl = document.body.outerHTML
}
@ -397,6 +447,7 @@ const domainRules = [
{ test: url => url.includes("acrofan.com") && document.querySelectorAll('[id^="wide"]').length > 0, handler: handleAcrofan },
{ test: url => url.includes("yna.co.kr") && document.querySelectorAll('[class^="wrapper"]').length > 0, handler: handleYna },
{ test: url => url.includes("yt1d.com/"), handler: ytDown },
{ test: url => url.includes("daum.net/dotax/"), handler: autoScrollAndHandleDotax },
{ test: url => url.includes("clien") && document.querySelectorAll('[class^="content_view"]').length > 0, handler: handleClien },
{ test: url => url.includes("toki") && (document.querySelectorAll('[id^="id_mbv"]').length > 0 || document.querySelectorAll('[class^="basic-banner"]').length > 0), handler: handleToki },
];
@ -779,20 +830,20 @@ function handleDcinside() {
'[id^="view_btn_area"], [class^="trend-rank"], [class^="view-btm-con"], [class^="md-tit-box"], [class^="gall-detail-lst"], [class^="outside-search-box"], [class^="footer ftlong"], [class^="adv-group"], li[style^="cursor:default;"], [id^="div_adnmore_area"]'
).forEach(e => e.remove());
}catch (e) {
}
try {
document.querySelectorAll('div[class^="imgwrap"]').forEach(function (e) {
try {e.style.backgroundColor = 'red';} catch (e) {}
})
})
} catch (e) {
}
try {
document.querySelectorAll('div[class^="imgwrap"]')[0].click()
}catch (e) {
}
mainContentsEl = document.querySelector('div[class="container"]');
}
@ -819,4 +870,36 @@ function handleClien() {
function handleToki() {
document.querySelectorAll('[id^="id_mbv"], [class^="basic-banner"]').forEach(e => e.remove());
}
}
function delaysend() {
if(location.pathname.endsWith("Elgq")) {
sendMessage(
{
type: "DOTAX"
}
);
}
}
function autoScrollAndHandleDotax() {
if(location.pathname.endsWith("Elgq")) {
//
//
// let count = 0;
// const scrollAmount = 800;
// const maxCount = 8;
//
// function scrollAndSend() {
// window.scrollBy(0, scrollAmount);
delaysend();
// count++;
// if (count < maxCount) {
// setTimeout(scrollAndSend, 1500); // 1초 후 재실행
// }
// }
//
// // 시작
// scrollAndSend();
// }
}

View File

@ -63,6 +63,7 @@ import bums.lunatic.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
import bums.lunatic.launcher.helpers.ForeGroundService
import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver
import bums.lunatic.launcher.home.GeckoWeb
import bums.lunatic.launcher.home.RssHome
import bums.lunatic.launcher.home.RssViewBuilder
import bums.lunatic.launcher.model.RssData
@ -112,52 +113,20 @@ open class LauncherActivity : CommonActivity() {
@JvmStatic var lActivity: LauncherActivity? = null
// fun refreshDeviceData()
// {
//
// mWorkManager?.cancelAllWorkByTag(SMS_WORK_TAG)
// mWorkManager?.enqueueUniquePeriodicWork(
// SMS_WORK_TAG,
// ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
// PeriodicWorkRequestBuilder<RecentSmsGetter>(PrefLong.longTimePeriod.get(), TimeUnit.MINUTES)
// .addTag(SMS_WORK_TAG)
// .build())
// mWorkManager?.cancelAllWorkByTag(RecentCallGetter.TAG)
// mWorkManager?.enqueueUniquePeriodicWork(
// RecentCallGetter.TAG,
// ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
// PeriodicWorkRequestBuilder<RecentCallGetter>(PrefLong.longTimePeriod.get(), TimeUnit.MINUTES)
// .addTag(RecentCallGetter.TAG)
// .build())
//
// mWorkManager?.cancelAllWorkByTag(ContactInfoGetter.TAG)
// mWorkManager?.enqueueUniquePeriodicWork(
// ContactInfoGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
// PeriodicWorkRequestBuilder<ContactInfoGetter>(12, TimeUnit.HOURS)
// .addTag(ContactInfoGetter.TAG)
// .build())
//
// mWorkManager?.enqueue(OneTimeWorkRequest.from(AppInfoGetter::class.java))
//
// }
// fun runWeatherGetter() {
// Executors.newSingleThreadScheduledExecutor().schedule({
// mWorkManager?.enqueue(OneTimeWorkRequest.from(OpenWeatherGetter::class.java))
// }, 200L, TimeUnit.MILLISECONDS)
// }
// fun getCal() {
// Executors.newSingleThreadScheduledExecutor().schedule({
// mWorkManager?.enqueue(OneTimeWorkRequest.from(CalendarGetter::class.java))
// }, 5, TimeUnit.SECONDS)
// }
}
var hiddenLoader : GeckoWeb? = null
fun contentsLoad(url : String){
if (isDestroyed == false && isFinishing == false) {
if (hiddenLoader == null) {
GeckoWeb(this).apply {
hiddenLoader = this
loadUrl(url)
}
} else {
hiddenLoader?.loadUrl(url)
}
}
}
@SuppressLint("MissingSuperCall")
override fun onConfigurationChanged(newConfig: Configuration) {
@ -171,23 +140,7 @@ open class LauncherActivity : CommonActivity() {
val nullCursor = PointerIcon.getSystemIcon(this, PointerIcon.TYPE_NULL)
binding.root.setPointerIcon(nullCursor)
}
// override fun onKeyClick(keyCode: Int): Boolean {
// when (keyCode) {
// KeyEvent.KEYCODE_VOLUME_DOWN -> {
// actionNextEvent()
// }
//
// KeyEvent.KEYCODE_VOLUME_UP -> {
// actionPrevEvent()
// }
//
// KeyEvent.KEYCODE_VOLUME_MUTE -> {
// actionNextEvent()
// }
//
// }
// return super.onKeyClick(keyCode)
// }
var actionButtonPressX = 0f
var actionButtonPressY = 0f
var onExit = false
@ -257,28 +210,36 @@ open class LauncherActivity : CommonActivity() {
return true
}
else {
if(MotionEvent.ACTION_UP.equals(ev?.action ?: MotionEvent.ACTION_CANCEL) == true) {
return when (ev.keyCode) {
KeyEvent.KEYCODE_VOLUME_DOWN -> {
if(currentFragment is Novels){ currentFragment.actionNextEvent() }
true
val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
when(currentFragment) {
is Novels -> {
if(MotionEvent.ACTION_UP.equals(ev?.action ?: MotionEvent.ACTION_CANCEL) == true) {
return when (ev.keyCode) {
KeyEvent.KEYCODE_VOLUME_DOWN -> {
if(currentFragment is Novels){ currentFragment.actionNextEvent() }
true
}
KeyEvent.KEYCODE_VOLUME_UP -> {
if(currentFragment is Novels){ currentFragment.actionPrevEvent() }
true
}
else -> false
}
} else {
return when (ev.keyCode) {
KeyEvent.KEYCODE_VOLUME_DOWN -> {
true
}
KeyEvent.KEYCODE_VOLUME_UP -> {
true
}
else -> false
}
}
KeyEvent.KEYCODE_VOLUME_UP -> {
if(currentFragment is Novels){ currentFragment.actionPrevEvent() }
true
}
else -> false
}
} else {
return when (ev.keyCode) {
KeyEvent.KEYCODE_VOLUME_DOWN -> {
true
}
KeyEvent.KEYCODE_VOLUME_UP -> {
true
}
else -> false
}
else -> return super.dispatchKeyEvent(ev)
}
}
return super.dispatchKeyEvent(ev)

View File

@ -22,6 +22,7 @@ import android.app.Application
import android.content.ComponentCallbacks2
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import bums.lunatic.launcher.helpers.HourlyLogWriter
import bums.lunatic.launcher.helpers.PrefHelper
import bums.lunatic.launcher.utils.Blog
import com.squareup.picasso.OkHttp3Downloader
@ -41,7 +42,7 @@ import java.util.concurrent.TimeUnit
internal class LunaticLauncher : Application() {
companion object {
var appContext : LunaticLauncher? = null
var mHourlyLogWriter : HourlyLogWriter? = null
}
override fun onCreate() {
@ -49,7 +50,14 @@ internal class LunaticLauncher : Application() {
appContext = this
Base.initialize(this)
PrefHelper.initialize(this)
val dir = File("/storage/emulated/0/bums_ob/BUM'S PACED /scraped/logs")
///BUM'S PACED/pdfs
if (!dir.exists()) {
dir.mkdirs()
} else {
dir.listFiles().forEach { Blog.LOGE("child -> ${it.absolutePath}") }
}
mHourlyLogWriter = HourlyLogWriter(dir)
val cacheSize = 1024L * 1024 * 1024 // 60MB
val cache = Cache(File(this.filesDir, "picasso-cache"), cacheSize)
val okHttpClient = OkHttpClient.Builder()

View File

@ -0,0 +1,43 @@
package bums.lunatic.launcher.helpers
import android.content.Context
import bums.lunatic.launcher.utils.Blog
import kotlinx.coroutines.*
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.atomic.AtomicReference
class HourlyLogWriter(private val logDir: File) {
private val ioScope = CoroutineScope(Dispatchers.IO)
private val lastFilePath = AtomicReference<String?>(null)
// 파일명 생성 (yyyyMMdd_HH)
private fun getLogFileName(): String {
val sdf = SimpleDateFormat("yyyyMMdd_HH", Locale.getDefault())
return "${sdf.format(Date())}.text"
}
// 로그 기록 함수 (비동기)
fun writeLog(data: String) {
Blog.LOGE("writeLog >>> ${data}")
ioScope.launch {
try {
if (!logDir.exists()) logDir.mkdirs()
val fileName = getLogFileName()
val logFile = File(logDir, fileName)
// 파일이 바뀌었으면 기록 경로 갱신
lastFilePath.set(logFile.absolutePath)
logFile.appendText("${System.currentTimeMillis()},$data\n")
Blog.LOGE("writeLog >>> ${logFile.length()}")
} catch (e: Exception) {
e.printStackTrace()
}
}
}
// 최근 로그 파일 경로 조회 (1시간 단위)
fun getCurrentLogFilePath(): String? = lastFilePath.get()
}

View File

@ -44,6 +44,7 @@ enum class PrefBoolean : PrefKey<Boolean> {
location,
rootPermisssion,
isConnectedCar,
usePublicTransportation,
useQuickLaunch,
openWithKayboard,
showAppResultCount,

View File

@ -38,8 +38,12 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.work.Worker
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.model.Dotax
import bums.lunatic.launcher.model.DotaxArticles
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.model.others.Button
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.view.BWebview
@ -51,6 +55,7 @@ import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter
import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLRequest
import com.yausername.youtubedl_android.YoutubeDLResponse
import io.realm.kotlin.ext.isValid
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -117,6 +122,7 @@ class GeckoWeb : BWebview {
session.navigationDelegate = navigationDelegate
it.webExtensionController.setAddonManagerDelegate(addonManagerDelegate)
session.mediaDelegate = mediaDelegate
session.promptDelegate = promptDelegate
session.mediaSessionDelegate = mediaSessionDelegate
// session.permissionDelegate = (object : PermissionDelegate {
// override fun onContentPermissionRequest(
@ -236,7 +242,32 @@ class GeckoWeb : BWebview {
}
}
val promptDelegate = object : GeckoSession.PromptDelegate {
override fun onAlertPrompt(
session: GeckoSession,
prompt: GeckoSession.PromptDelegate.AlertPrompt
): GeckoResult<GeckoSession.PromptDelegate.PromptResponse?>? {
if(lastedUrl?.contains("daum.net/dotax") == true) {
try {
Gson().fromJson<DotaxArticles>(prompt.message,DotaxArticles::class.java)?.let {
Blog.LOGE("it.Articles >>> ${it.Articles?.size}")
it.Articles?.forEach {
Dotax("${it.fldid}/${it.dataid}","dotax",it.articleElapsedTime!!,it.title!!,it.thumbnailImageUrl!!)?.let {
it.getRssData().let {
WorkersDb.insertData(it)
}
}
}
}
} catch (e: Exception) {
}
}
Blog.LOGE("prompt >>> ${prompt.message}")
prompt.dismiss()
return super.onAlertPrompt(session, prompt)
}
}
val mediaDelegate = object : GeckoSession.MediaDelegate {
override fun onRecordingStatusChanged(
session: GeckoSession,
@ -681,11 +712,11 @@ class GeckoWeb : BWebview {
) {
if (element.baseUri?.contains("youtube") == true) {
lastedUrl?.let { videoUrl ->
lastedUrl?.let {
videoDlownLoad(it)
}
}
// lastedUrl?.let { videoUrl ->
// lastedUrl?.let {
// videoDlownLoad(it)
// }
// }
} else {
Blog.LOGE("onContextMenu:: x = ${x}, y = ${y} , element = ${Gson().toJson(element)}")
if (element.type == GeckoSession.ContentDelegate.ContextElement.TYPE_IMAGE) {
@ -859,6 +890,8 @@ class GeckoWeb : BWebview {
lastedUrl = url
}
checkIfDownloadable(url)
}
@ -924,6 +957,12 @@ class GeckoWeb : BWebview {
}
"SHOWVIEWER" -> {
}
"DOTAX"->{
val script = "alert(JSON.stringify({Articles : window.articles}))"
val encodedJs = Uri.encode(script)
val jsUri = "javascript:$encodedJs"
session?.loadUri(jsUri)
}
"PRIVATES"->{
lPortMessage.privates?.let {
context.toast("Received Msg privates form ${lPortMessage.currentPage} data => ${it?.size ?: 0}")

View File

@ -301,6 +301,30 @@ class RssData : RealmObject, RssDataInterface {
}
class DotaxArticles {
var Articles : ArrayList<DotaxArticle> ? = null
}
class DotaxArticle {
var dataid : String? = null //4623278
var fldid : String? = null //"Elgq"
var title : String? = null //"손 크다고 자랑하는 여직원"
var thumbnailImageUrl : String? = null //"https://img1.daumcdn.net/thumb/C52x52/?fname=https://t1.daumcdn.net/cafeattach/mEr9/e62d71b492cb60155d32a649df324a990564c06f"
var viewCount : String? = null //116
var commentCount : String? = null //0
var writerNickname : String? = null //"녹두로로"
var articleElapsedTime : String? = null //"방금전"
var hasMovie : String? = null //false
var hasParentArticle : String? = null //false
var articleWriter : String? = null //false
var newArticle : String? = null //true
var headCont : String? = null //""
var escrow : String? = null //false
var hasSoldItem : String? = null //false
var bbsDepth : String? = null //"0JOj0zzzzzzzzzzzzzzzzzzzzzzzzz"
}
open class Dotax(var pageLink : String,
var desc : String,
var dateTime : String,
@ -323,7 +347,7 @@ open class Dotax(var pageLink : String,
}
override fun originPage(): String {
return "https://m.cafe.daum.net".plus(pageLink)
return "https://m.cafe.daum.net/dotax/".plus(pageLink)
}
override fun description(): String {

View File

@ -1,11 +1,14 @@
package bums.lunatic.launcher.receiver
import android.Manifest
import android.app.Notification
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.location.Geocoder
import android.location.Location
import android.media.MediaMetadata
import android.media.session.MediaSessionManager
import android.media.session.PlaybackState.STATE_PLAYING
@ -13,15 +16,41 @@ import android.os.Build
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission
import androidx.core.content.getSystemService
import bums.lunatic.launcher.LunaticLauncher.Companion.mHourlyLogWriter
import bums.lunatic.launcher.common.letTrue
import bums.lunatic.launcher.helpers.ForeGroundService
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_SENDMSG
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.EXTRA_MSGKEY
import bums.lunatic.launcher.helpers.PrefBoolean
import bums.lunatic.launcher.helpers.PrefString
import bums.lunatic.launcher.model.CurrentPlayItem
import bums.lunatic.launcher.model.LocationLog
import bums.lunatic.launcher.model.NotificationItem
import bums.lunatic.launcher.utils.BitmapConverter
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.workers.LocationUpdateService.Companion.inRangeLocation
import bums.lunatic.launcher.workers.WorkersDb
import com.google.android.gms.location.LocationServices
import com.google.gson.Gson
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import io.realm.kotlin.query.Sort
import okhttp3.ConnectionPool
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import okhttp3.ResponseBody
import java.io.File
import java.io.IOException
import java.lang.Exception
import java.util.Base64
import java.util.Locale
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
class NLService : NotificationListenerService() {
@ -46,12 +75,6 @@ class NLService : NotificationListenerService() {
Blog.LOGE("onNotificationPosted ${sbn}")
val notification = sbn.notification
val extras = notification.extras
when (sbn.packageName){
"com.kakao.talk" -> {
}
}
val title = extras.getString(Notification.EXTRA_TITLE) ?: ""
val text = extras.getCharSequence(Notification.EXTRA_TEXT)?.toString() ?: ""
val bigText = extras.getCharSequence(Notification.EXTRA_BIG_TEXT)?.toString() ?: ""
@ -60,9 +83,72 @@ class NLService : NotificationListenerService() {
val conversationTitle = extras.getCharSequence(Notification.EXTRA_CONVERSATION_TITLE)?.toString() ?: ""
val summaryText = extras.getCharSequence(Notification.EXTRA_SUMMARY_TEXT)?.toString() ?: ""
val verificationText = extras.getCharSequence(Notification.EXTRA_VERIFICATION_TEXT)?.toString() ?: ""
val stringBuffer = StringBuffer()
stringBuffer.append(title).append("\n")
stringBuffer.append(text).append("\n")
stringBuffer.append(bigText).append("\n")
stringBuffer.append(extraInfo).append("\n")
stringBuffer.append(subText).append("\n")
stringBuffer.append(conversationTitle).append("\n")
stringBuffer.append(summaryText).append("\n")
stringBuffer.append(verificationText).append("\n")
Blog.LOGE("title >> ${title} text >> ${text} bigText >> ${bigText} extraInfo >> ${extraInfo} subText >> ${subText} conversationTitle >> ${conversationTitle} summaryText >> ${summaryText} verificationText >> ${verificationText}")
mHourlyLogWriter?.writeLog("${sbn.packageName}\n${stringBuffer.toString()}")
when (sbn.packageName){
"com.kakao.talk" -> {
}
"kakaopay.app" -> {
if (stringBuffer.contains("모바일") && stringBuffer.contains("교통카드")) {
var usePublicTransportation = PrefBoolean.usePublicTransportation.get(false)
PrefBoolean.usePublicTransportation.set(!usePublicTransportation)
val actionIntent = Intent(this, ForeGroundService::class.java).apply {
action = ACTION_SENDMSG
putExtra(EXTRA_MSGKEY, "돼지가 대중교통에${if (!usePublicTransportation){" 탑승 "} else {" 하차"}} 했다요~!") // 전달할 데이터
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(actionIntent)
} else {
startService(actionIntent)
}
}
}
}
}
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
fun pushLocation(context: Context) {
try {
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
location?.let {
val latitude = it.latitude
val longitude = it.longitude
// 현 위치 사용
val geocoder = Geocoder(context, Locale.getDefault())
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
geocoder.getFromLocation(latitude, longitude, 1) { addresses ->
addresses.first()?.let {
it.getAddressLine(0)?.let { addr ->
val actionIntent = Intent(this, ForeGroundService::class.java).apply {
action = ACTION_SENDMSG
putExtra(EXTRA_MSGKEY, "대중교통 이용 위치:\n${addr}") // 전달할 데이터
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(actionIntent)
} else {
startService(actionIntent)
}
}
}
}
}
}
}
} catch (e: IOException) {
e.printStackTrace()
}
}
override fun onNotificationRemoved(sbn: StatusBarNotification) {

View File

@ -161,8 +161,7 @@ class PagedTextView : AppCompatTextView {
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
Blog.LOGD(log = "onSizeChanged>> ${this::class.java.name}")
pageHeight = ((h - (marginTop + marginBottom + paddingTop + paddingBottom)) * 1f).toInt()
pageHeight = h - (paddingTop + paddingBottom) // 마진 제외
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
@ -221,25 +220,27 @@ class PagedTextView : AppCompatTextView {
private fun from(layout: Layout): Layout =
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
@Suppress("DEPRECATION")
(StaticLayout(
StaticLayout(
originalText,
paint,
layout.width,
layout.width - paddingLeft - paddingRight, // margin 제외
layout.alignment,
lineSpacingMultiplier,
lineSpacingExtra,
includeFontPadding
))
)
} else {
StaticLayout.Builder
.obtain(originalText, 0, originalText.length, paint, ((layout.width - (paddingLeft + paddingRight + marginLeft + marginRight) * 0.85f)).toInt())
.obtain(
originalText, 0, originalText.length, paint,
(layout.width - paddingLeft - paddingRight)
)
.setAlignment(layout.alignment)
.setLineSpacing(lineSpacingExtra, lineSpacingMultiplier)
.setIncludePad(includeFontPadding)
.setUseLineSpacingFromFallbacks()
.setBreakStrategy(breakStrategy)
.setHyphenationFrequency(hyphenationFrequency)
// .setJustificationMode()
.setMaxLines(maxLines)
.build()
}

View File

@ -11,7 +11,11 @@ object RssList {
"https://www.youtube.com/@sungsikyung",
"https://www.youtube.com/@%EC%A7%80%EB%AC%B4%EB%B9%84",
"https://www.youtube.com/@gyeomsonisnothing",
"https://www.youtube.com/@ddeunddeun"
"https://www.youtube.com/@ddeunddeun",
"https://www.youtube.com/@fairyjaehyung",
"https://www.youtube.com/@15ya_egg",
"https://www.youtube.com/@%EC%A7%80%EB%AC%B4%EB%B9%84",
"https://www.youtube.com/"
)
val newsFeeds = arrayListOf(
"https://news.google.com/rss?hl=ko&gl=KR&ceid=KR:ko",

View File

@ -22,7 +22,7 @@ open abstract class BaseGetter : Worker {
}
}
val USAGT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
val USAGT = "Mozilla/5.0 (Android 15; Mobile; rv:141.0) Gecko/141.0 Firefox/141.0"
val limitDateTime = beforeOneDay()
val commicsDateTime = beforeDay(1)

View File

@ -3,10 +3,16 @@ package bums.lunatic.launcher.workers
import android.annotation.SuppressLint
import android.content.Context
import androidx.work.WorkerParameters
import bums.lunatic.launcher.LauncherActivity
import bums.lunatic.launcher.home.GeckoWeb
import bums.lunatic.launcher.model.Dotax
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.utils.Blog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jsoup.Jsoup
class DotaxGetter : BaseGetter {
@ -23,33 +29,41 @@ class DotaxGetter : BaseGetter {
try {
Blog.LOGE("realWork() ${this::class.simpleName}")
temp.clear()
val dotaxUrls = arrayListOf("https://m.cafe.daum.net/dotax",
"https://m.cafe.daum.net/dotax/_rec?page=2",
// "https://m.cafe.daum.net/dotax/_rec?page=3"
)
dotaxUrls?.forEach {
Jsoup.connect(it).userAgent(USAGT).get()?.let { dotax ->
dotax.getElementsByTag("li").forEach { dotax_li ->
Blog.LOGE("dotax_li >>> ${dotax_li.text()}")
if (dotax_li.getElementsByTag("a").size > 0 && dotax_li.getElementsByClass("board_name")
.html().contains("웃긴")
) {
val pageLink = dotax_li.getElementsByTag("a").get(0).attr("href")
val desc = dotax_li.getElementsByClass("board_name").text()
val dateTime = dotax_li.getElementsByClass("created_at").text()
val title = dotax_li.getElementsByClass("txt_detail").text()
val thumbnail = dotax_li.getElementsByClass("article_thumb").text()
if (pageLink.length > 0 && desc.length > 0 && dateTime.length > 0 && title.length > 0) {
Dotax(pageLink, desc, dateTime, title, thumbnail).let { dotax ->
if(dotax.pubDate() > commicsDateTime) {
temp.add(dotax.getRssData())
}
}
}
// val dotaxUrls = arrayListOf("https://cafe.daum.net/dotax",
// "https://m.cafe.daum.net/dotax/Elgq"
//// "https://m.cafe.daum.net/dotax/_rec?page=3"
// )
// dotaxUrls?.forEach { url ->
CoroutineScope(Dispatchers.Main).launch {
withContext(Dispatchers.Main) {
LauncherActivity.lActivity?.let {
it.contentsLoad("https://m.cafe.daum.net/dotax/Elgq")
}
}
}
}
// }
// dotaxUrls?.forEach {
// Jsoup.connect(it).timeout(3000).userAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36").get()?.let { dotax ->
// Blog.LOGE("dotax.html() >>> ${dotax.html()}")
// dotax.getElementsByTag("tr").forEach { dotax_li ->
// Blog.LOGE("dotax_li >>> ${dotax_li.text()}")
// if (dotax_li.getElementsByTag("a").size > 0) {
// val pageLink = dotax_li.getElementsByTag("a").get(0).attr("href")
// val desc = dotax_li.getElementsByClass("board_name").text()
// val dateTime = dotax_li.getElementsByClass("created_at").text()
// val title = dotax_li.getElementsByClass("txt_detail").text()
// val thumbnail = dotax_li.getElementsByClass("article_thumb").text()
// if (pageLink.length > 0 && desc.length > 0 && dateTime.length > 0 && title.length > 0) {
// Dotax(pageLink, desc, dateTime, title, thumbnail).let { dotax ->
// if(dotax.pubDate() > commicsDateTime) {
// temp.add(dotax.getRssData())
// }
// }
// }
// }
// }
// }
// }
} catch (e : Exception) {e.printStackTrace()}}
return Result.success().apply {
WorkersDb.insertBulkData(temp)

View File

@ -41,6 +41,7 @@ import java.util.concurrent.TimeUnit
class LocationUpdateService : Service(), LocationListener {
companion object {
fun pushLocation(context: Context, lat :Double, long : Double) {
try {
val geocoder = Geocoder(context, Locale.getDefault())
@ -176,6 +177,7 @@ class LocationUpdateService : Service(), LocationListener {
pushLocation(this.applicationContext, location.latitude, location.longitude)
}
}
} catch (e : Exception) {
}

View File

@ -25,7 +25,7 @@
android:layout_height="match_parent"/>
<View
android:id="@+id/demp"
android:visibility="gone"
android:visibility="invisible"
android:layout_margin="5dp"
android:layout_weight="1"
android:layout_width="0dp"
@ -55,7 +55,7 @@
android:gravity="start"
android:includeFontPadding="false"
android:lineSpacingExtra="0dp"
android:visibility="gone"
android:visibility="invisible"
android:id="@+id/sencond_view"
android:layout_width="0dp"
android:layout_weight="1"