Compare commits
No commits in common. "d1f080ded1540df7c358f7211c5ce1b7117aebde" and "2a25b49baa97b17ef97a5d89ea0a6cce4069cc74" have entirely different histories.
d1f080ded1
...
2a25b49baa
@ -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")
|
||||
|
||||
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
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
|
||||
@ -1 +0,0 @@
|
||||
java --telegram.bot.key=bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w --telegram.my.id=71476436 --telegram.target.id=71476436 --weather.api.key=de574a260b1f474d99955729241909 --spring.datasource.url=jdbc:mariadb://mra.sbspace.synology.me --spring.data.mongodb.uri=mongodb://lun_admin:VioPup*383@mongo.sbspace.synology.me/?wtimeoutMS=300&connectTimeoutMS=500&socketTimeoutMS=200 --spring.data.mongodb.database=lun_db --spring.datasource.username=lun_admin --spring.datasource.password=VioPup*383 --resource.handler=blog/post/image/** --resource.location=file:///usr/src/app/imgUpload --image.upload.path=/usr/src/app/imgUpload --api.gg.place=AIzaSyARLXyvmr_554tOy3UCh3naFlZQS3-qQQM
|
||||
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
||||
}
|
||||
//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);
|
||||
// }
|
||||
//}
|
||||
@ -569,11 +569,8 @@ internal class LauncherActivity : CommonActivity() {
|
||||
private fun initGeckoRuntime() {
|
||||
if (sRuntime == null) {
|
||||
try {
|
||||
sRuntime = GeckoRuntime.create(this, GeckoRuntimeSettings.Builder()
|
||||
.extensionsProcessEnabled(true)
|
||||
.extensionsWebAPIEnabled(true)
|
||||
.experimentDelegate(experimentDelegate)
|
||||
.debugLogging(false)
|
||||
sRuntime = GeckoRuntime.create(this, GeckoRuntimeSettings.Builder().extensionsProcessEnabled(true)
|
||||
.extensionsWebAPIEnabled(true).experimentDelegate(experimentDelegate)
|
||||
.remoteDebuggingEnabled(true).build())
|
||||
} catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
@ -720,7 +717,6 @@ internal class LauncherActivity : CommonActivity() {
|
||||
}
|
||||
val callBackHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -73,9 +73,9 @@ class BluetoothManager : Service() {
|
||||
val filter = IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED)
|
||||
registerReceiver(bluetoothreceiver, filter)
|
||||
refreshFeeds()
|
||||
GeckoWeb(applicationContext).apply {
|
||||
loadUrl("https://arca.live/b/live")
|
||||
}
|
||||
// GeckoWeb(applicationContext).apply {
|
||||
// loadUrl("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=")
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
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<HtmlNodeRendererHandler<*>> {
|
||||
return setOf(
|
||||
HtmlNodeRendererHandler(
|
||||
"video", // 처리할 태그명!
|
||||
Element::class.java
|
||||
) { node, context, markdown ->
|
||||
// node: org.jsoup.nodes.Element 타입, 즉 <video ...> 태그
|
||||
val sources = node.getElementsByTag("source")
|
||||
val src = if (sources.isNotEmpty()) {
|
||||
sources.first()?.attr("src")
|
||||
} else {
|
||||
node.attr("src")
|
||||
}
|
||||
// 대표 src가 있으면 단일 <video src=... controls></video>
|
||||
if (src?.isNotBlank() == true) {
|
||||
markdown.append("<video src=\"$src\" controls></video>\n")
|
||||
} else {
|
||||
// 혹시 src 속성이 없거나 source 태그가 없으면 원본 전체 남김
|
||||
markdown.append(node.outerHtml() + "\n")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package bums.lunatic.launcher.home
|
||||
|
||||
import CustomVideoNodeRenderer
|
||||
import android.app.DownloadManager
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
@ -9,6 +8,9 @@ import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.util.AttributeSet
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
@ -24,36 +26,36 @@ import android.view.KeyEvent.KEYCODE_DPAD_DOWN
|
||||
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CheckBox
|
||||
import android.widget.EditText
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.isVisible
|
||||
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.tokiz.data.HistoryManager
|
||||
import bums.lunatic.launcher.tokiz.data.model.History
|
||||
import bums.lunatic.launcher.tokiz.data.model.PortMessage
|
||||
import bums.lunatic.launcher.tokiz.view.BWebview
|
||||
import bums.lunatic.launcher.tokiz.view.JxEvent
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import bums.lunatic.launcher.utils.afterDay
|
||||
import bums.lunatic.launcher.workers.WorkersDb
|
||||
import bums.lunatic.launcher.workers.WorkersDb.getRealm
|
||||
import com.google.gson.Gson
|
||||
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import io.realm.kotlin.UpdatePolicy
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.mozilla.gecko.util.ThreadUtils
|
||||
import org.mozilla.geckoview.ExperimentDelegate
|
||||
import org.mozilla.geckoview.GeckoResult
|
||||
import org.mozilla.geckoview.GeckoRuntime
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings
|
||||
import org.mozilla.geckoview.GeckoSession
|
||||
import org.mozilla.geckoview.GeckoSession.PermissionDelegate
|
||||
import org.mozilla.geckoview.GeckoView
|
||||
import org.mozilla.geckoview.MediaSession
|
||||
import org.mozilla.geckoview.WebExtension
|
||||
import org.mozilla.geckoview.WebExtension.MessageDelegate
|
||||
@ -61,10 +63,7 @@ import org.mozilla.geckoview.WebExtension.PortDelegate
|
||||
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
|
||||
import org.mozilla.geckoview.WebRequestError
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
|
||||
class GeckoWeb : BWebview {
|
||||
constructor(context: Context?) : super(context) {
|
||||
@ -85,7 +84,6 @@ class GeckoWeb : BWebview {
|
||||
val extId = "messaging@booktoki468.com"
|
||||
|
||||
private fun buildWeb() {
|
||||
|
||||
getRuntime()?.let {
|
||||
val session: GeckoSession = GeckoSession()
|
||||
session.open(it)
|
||||
@ -96,38 +94,6 @@ class GeckoWeb : BWebview {
|
||||
it.webExtensionController.setAddonManagerDelegate(addonManagerDelegate)
|
||||
session.mediaDelegate = mediaDelegate
|
||||
session.mediaSessionDelegate = mediaSessionDelegate
|
||||
// session.permissionDelegate = (object : PermissionDelegate {
|
||||
// override fun onContentPermissionRequest(
|
||||
// session: GeckoSession,
|
||||
// perm: PermissionDelegate.ContentPermission
|
||||
// ): GeckoResult<Int?>? {
|
||||
//
|
||||
// return super.onContentPermissionRequest(session, perm)
|
||||
// }
|
||||
//
|
||||
// override fun onAndroidPermissionsRequest(
|
||||
// session: GeckoSession,
|
||||
// permissions: Array<out String?>?,
|
||||
// callback: PermissionDelegate.Callback
|
||||
// ) {
|
||||
// super.onAndroidPermissionsRequest(session, permissions, callback)
|
||||
// }
|
||||
//
|
||||
// override fun onMediaPermissionRequest(
|
||||
// session: GeckoSession,
|
||||
// uri: String,
|
||||
// video: Array<out PermissionDelegate.MediaSource?>?,
|
||||
// audio: Array<out PermissionDelegate.MediaSource?>?,
|
||||
// callback: PermissionDelegate.MediaCallback
|
||||
// ) {
|
||||
//
|
||||
// // 첫 번째 비디오·오디오 소스를 허용
|
||||
//
|
||||
// callback.grant(video?.firstOrNull(), audio?.firstOrNull())
|
||||
// }
|
||||
//
|
||||
//
|
||||
// });
|
||||
it.webExtensionController
|
||||
.ensureBuiltIn(extPath, extId)
|
||||
.accept( // Register message delegate for background script
|
||||
@ -309,108 +275,30 @@ class GeckoWeb : BWebview {
|
||||
}
|
||||
|
||||
fun showImageDownloadDialog(context: Context, imageUrl: Uri) {
|
||||
|
||||
}
|
||||
|
||||
fun savePdfStreamToFile(pdfStream: InputStream?, outputFile: File) {
|
||||
pdfStream?.let {
|
||||
FileOutputStream(outputFile).use { output ->
|
||||
val buffer = ByteArray(8 * 1024)
|
||||
var bytesRead: Int
|
||||
while (pdfStream.read(buffer).also { bytesRead = it } != -1) {
|
||||
output.write(buffer, 0, bytesRead)
|
||||
}
|
||||
output.flush()
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle("이미지 다운로드")
|
||||
.setMessage("이미지를 저장하시겠습니까?")
|
||||
.setPositiveButton("저장") { _, _ ->
|
||||
downloadImage(context, imageUrl)
|
||||
}
|
||||
pdfStream.close()
|
||||
}
|
||||
.setNegativeButton("취소", null)
|
||||
.show()
|
||||
}
|
||||
|
||||
// 실제 사용 예시
|
||||
|
||||
fun scrapWebToMd(context: Context, url: Uri?, markdownText: String) {
|
||||
// 경로 선언 (예: /storage/emulated/0/fff_gg/pdfs)
|
||||
val dir = File("/storage/emulated/0/bums_ob/BUM'S PACED /scraped/md")
|
||||
///BUM'S PACED/pdfs
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs()
|
||||
} else {
|
||||
dir.listFiles().forEach { Blog.LOGE("child -> ${it.absolutePath}") }
|
||||
}
|
||||
val outputFile = File(dir, "${url?.host ?: "UnKnown"}_scraped_${SimpleDateFormat("yyyyMMdd-HHmm").format(Date())}.md")
|
||||
outputFile.writeText(markdownText, Charsets.UTF_8)
|
||||
// 저장 성공 알림 등 후속 처리
|
||||
println("PDF 저장 완료: ${outputFile.absolutePath}")
|
||||
|
||||
}
|
||||
|
||||
fun downloadImage(context: Context, url: Uri, isGif : Boolean = false) {
|
||||
fun downloadImage(context: Context, url: Uri) {
|
||||
Blog.LOGE("url.lastPathSegment ${url.lastPathSegment}")
|
||||
val fileName = url.host + "_${SimpleDateFormat("yyyyMMddHHmmsss").format(Date())}.${if(isGif){"gif"}else{"jpg"}}"
|
||||
val fileName = url.lastPathSegment ?: "${SimpleDateFormat("yyyyMMddHHmmsss")}.jpg"
|
||||
val request = DownloadManager.Request(url)
|
||||
request.setTitle(fileName)
|
||||
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
|
||||
request.setDescription("이미지 다운로드 중...")
|
||||
request.setAllowedOverMetered(true) // 선택 사항 - 데이터 요금제 네트워크에서도 허용
|
||||
request.setVisibleInDownloadsUi(true)
|
||||
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
|
||||
// 네트워크타입, 알림설정 등 옵션 추가 가능
|
||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
||||
|
||||
val dm = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
|
||||
|
||||
dm.enqueue(request)
|
||||
Toast.makeText(context, "다운로드 시작: $fileName", Toast.LENGTH_SHORT).show()
|
||||
val downloadId = dm.enqueue(request)
|
||||
monitorDownloadStatus(dm, downloadId, context)
|
||||
}
|
||||
fun monitorDownloadStatus(dm: DownloadManager, downloadId: Long, context: Context) {
|
||||
val handler = CoroutineExceptionHandler { _, exception ->
|
||||
// 에러 처리 로직 (선택)
|
||||
exception.printStackTrace()
|
||||
}
|
||||
|
||||
// 백그라운드에서 5초 간격으로 상태 체크
|
||||
CoroutineScope(Dispatchers.IO + handler).launch {
|
||||
while (true) {
|
||||
val query = DownloadManager.Query().setFilterById(downloadId)
|
||||
val cursor = dm.query(query)
|
||||
var downloadFinished = false
|
||||
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
|
||||
when (status) {
|
||||
DownloadManager.STATUS_SUCCESSFUL -> {
|
||||
// 다운로드 성공 처리
|
||||
withContext(Dispatchers.Main) {
|
||||
// UI 갱신 등 메인 스레드 작업 (필요 시)
|
||||
}
|
||||
downloadFinished = true
|
||||
}
|
||||
DownloadManager.STATUS_FAILED -> {
|
||||
val reason = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_REASON))
|
||||
// 여기에 reason값에 따라 적절한 처리 또는 로깅 수행
|
||||
Log.e("DownloadManager", "Download failed with reason code: $reason")
|
||||
// 다운로드 실패 처리
|
||||
withContext(Dispatchers.Main) {
|
||||
// UI 갱신 등 메인 스레드 작업 (필요 시)
|
||||
}
|
||||
downloadFinished = true
|
||||
}
|
||||
else -> {
|
||||
Blog.LOGE("DownloadManager.STATUS >> ${status}")
|
||||
}
|
||||
// 진행 중, 대기 중 등 기타 상태는 계속 확인
|
||||
}
|
||||
}
|
||||
cursor?.close()
|
||||
|
||||
if (downloadFinished) break
|
||||
|
||||
delay(5000L) // 5초 대기 후 다시 반복
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getFilterF() = String(java.util.Base64.getMimeDecoder().decode("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=".toByteArray()))
|
||||
val contentDelegate = object : GeckoSession.ContentDelegate {
|
||||
override fun onTitleChange(
|
||||
@ -473,8 +361,6 @@ class GeckoWeb : BWebview {
|
||||
}
|
||||
override fun onPageStart(session: GeckoSession, url: String) {
|
||||
super.onPageStart(session, url)
|
||||
markdownContents = null
|
||||
markdownUri = null
|
||||
if (url.contains(getFilterF()) && privateMode) {
|
||||
this@GeckoWeb.visibility = View.INVISIBLE
|
||||
}
|
||||
@ -532,17 +418,14 @@ class GeckoWeb : BWebview {
|
||||
loadUrl(uri)
|
||||
} else {
|
||||
val builder: AlertDialog.Builder = AlertDialog.Builder(context)
|
||||
builder.setTitle("Move To\n${uri}")
|
||||
builder.setTitle("Move To")
|
||||
val viewInflated: View = LayoutInflater.from(context)
|
||||
.inflate(R.layout.text_inpu_password, null, false)
|
||||
val input = viewInflated.findViewById<View>(R.id.input) as EditText
|
||||
(viewInflated.findViewById<CheckBox>(R.id.add_vote) as CheckBox)?.let { it.visibility = View.GONE }
|
||||
(viewInflated.findViewById<CheckBox>(R.id.add_read) as CheckBox)?.let { it.visibility = View.GONE }
|
||||
(viewInflated.findViewById<CheckBox>(R.id.private_mode) as CheckBox)?.let { it.visibility = View.GONE }
|
||||
input.visibility = View.GONE
|
||||
builder.setView(viewInflated)
|
||||
builder.setPositiveButton(
|
||||
"브라우저로 이동",
|
||||
android.R.string.ok,
|
||||
DialogInterface.OnClickListener { dialog, which ->
|
||||
dialog.dismiss()
|
||||
context.startActivity(Intent().apply {
|
||||
@ -552,12 +435,6 @@ class GeckoWeb : BWebview {
|
||||
data = it
|
||||
})
|
||||
})
|
||||
builder.setNeutralButton(
|
||||
"페이지 이동",
|
||||
DialogInterface.OnClickListener { dialog, which ->
|
||||
loadUrl(uri)
|
||||
dialog.cancel()
|
||||
})
|
||||
builder.setNegativeButton(
|
||||
android.R.string.cancel,
|
||||
DialogInterface.OnClickListener { dialog, which -> dialog.cancel() })
|
||||
@ -604,16 +481,6 @@ class GeckoWeb : BWebview {
|
||||
}
|
||||
|
||||
}
|
||||
fun saveMd() {
|
||||
val message: JSONObject = JSONObject()
|
||||
try {
|
||||
message.put("type", "saveContent")
|
||||
} catch (ex: JSONException) {
|
||||
throw RuntimeException(ex)
|
||||
}
|
||||
Blog.LOGE(Gson().toJson(message))
|
||||
mPort?.postMessage(message)
|
||||
}
|
||||
|
||||
val portDelegate: PortDelegate =
|
||||
object : PortDelegate {
|
||||
@ -653,27 +520,6 @@ class GeckoWeb : BWebview {
|
||||
|
||||
}
|
||||
}
|
||||
"MainContentsEl"->{
|
||||
try {
|
||||
val doc: Document = Jsoup.parse(lPortMessage.contents)
|
||||
val combinedHtml = doc.html()
|
||||
val converter = FlexmarkHtmlConverter.builder().htmlNodeRendererFactory { options -> CustomVideoNodeRenderer(options) }.build()
|
||||
markdownContents = converter.convert(combinedHtml)
|
||||
markdownUri = lPortMessage.currentPage?.toUri()
|
||||
markdownContents?.let {
|
||||
if (it.length > 40) {
|
||||
scrapWebToMd(context, markdownUri, it)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
markdownContents = null
|
||||
markdownUri = null
|
||||
}
|
||||
|
||||
|
||||
// scrapWepToMd(context, Uri.parse(lPortMessage.currentPage), markdown)
|
||||
|
||||
}
|
||||
else -> {
|
||||
|
||||
}
|
||||
@ -696,9 +542,6 @@ class GeckoWeb : BWebview {
|
||||
}
|
||||
}
|
||||
|
||||
var markdownContents : String? = null
|
||||
var markdownUri : Uri? = null
|
||||
|
||||
val cacheDelegate: PortDelegate =
|
||||
object : PortDelegate {
|
||||
override fun onPortMessage(
|
||||
|
||||
@ -277,9 +277,7 @@ internal class RssHome : Fragment() {
|
||||
val viewInflated: View = LayoutInflater.from(requireContext())
|
||||
.inflate(R.layout.text_inpu_password, binding.root as ViewGroup?, false)
|
||||
val input = viewInflated.findViewById<View>(R.id.input) as EditText
|
||||
val privateMode = viewInflated.findViewById<CheckBox>(R.id.private_mode) as CheckBox
|
||||
val addVote = viewInflated.findViewById<CheckBox>(R.id.add_vote) as CheckBox
|
||||
val addRead = viewInflated.findViewById<CheckBox>(R.id.add_read) as CheckBox
|
||||
val privateMode = viewInflated.findViewById<CheckBox>(R.id.parivate_mode) as CheckBox
|
||||
privateMode.setOnCheckedChangeListener { v,c->
|
||||
binding.geckoWeb.privateMode = c
|
||||
}
|
||||
@ -292,7 +290,7 @@ internal class RssHome : Fragment() {
|
||||
dialog.dismiss()
|
||||
var command = input.editableText?.toString()
|
||||
if (command?.length ?: 0 > 0) {
|
||||
queryInfos(keywords = command!!.split(" ")!!, addVote.isChecked, addRead.isChecked)
|
||||
queryInfos(keywords = command!!.split(" ")!!)
|
||||
}
|
||||
})
|
||||
builder.setNegativeButton(
|
||||
@ -303,16 +301,13 @@ internal class RssHome : Fragment() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun ask() {
|
||||
val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
|
||||
builder.setTitle("Command Line")
|
||||
val viewInflated: View = LayoutInflater.from(requireContext())
|
||||
.inflate(R.layout.text_inpu_password, binding.root as ViewGroup?, false)
|
||||
val input = viewInflated.findViewById<View>(R.id.input) as EditText
|
||||
val privateMode = viewInflated.findViewById<CheckBox>(R.id.private_mode) as CheckBox
|
||||
(viewInflated.findViewById<CheckBox>(R.id.add_vote) as CheckBox)?.let{ it.visibility = View.GONE}
|
||||
(viewInflated.findViewById<CheckBox>(R.id.add_read) as CheckBox)?.let{ it.visibility = View.GONE}
|
||||
val privateMode = viewInflated.findViewById<CheckBox>(R.id.parivate_mode) as CheckBox
|
||||
privateMode.setOnCheckedChangeListener { v,c->
|
||||
binding.geckoWeb.privateMode = c
|
||||
}
|
||||
@ -452,9 +447,6 @@ internal class RssHome : Fragment() {
|
||||
vote()
|
||||
}
|
||||
}
|
||||
binding.share.setOnClickListener {
|
||||
binding.geckoWeb.saveMd()
|
||||
}
|
||||
Blog.LOGE("useHiddenMenu >>> $useHiddenMenu")
|
||||
if (useHiddenMenu) {
|
||||
binding.search.setOnLongClickListener {
|
||||
@ -541,7 +533,6 @@ internal class RssHome : Fragment() {
|
||||
}
|
||||
|
||||
queryInfos()
|
||||
|
||||
binding.geckoWeb.progress = binding.progressBar
|
||||
binding.geckoWeb.jxInteface = { jxEvent ->
|
||||
when (jxEvent) {
|
||||
@ -569,7 +560,6 @@ internal class RssHome : Fragment() {
|
||||
}
|
||||
|
||||
fun vote() {
|
||||
binding.geckoWeb?.saveMd()
|
||||
currentRss?.originPage.let {
|
||||
Blog.LOGE("Arrow Center Click")
|
||||
WorkersDb.getRealm().apply {
|
||||
@ -637,7 +627,6 @@ internal class RssHome : Fragment() {
|
||||
}
|
||||
|
||||
fun updateQuery(q: RealmQuery<RssData>) {
|
||||
Blog.LOGE("updateQuery >>> ${q.description()}")
|
||||
infosJob?.cancel()
|
||||
commandHandler.removeCallbacks(infoUpdate)
|
||||
|
||||
|
||||
@ -188,64 +188,59 @@ internal class RssItemAdapter (
|
||||
|
||||
@SuppressLint("SetTextI18n", "ClickableViewAccessibility")
|
||||
override fun onBindViewHolder(holder: RssHolder, position: Int) {
|
||||
synchronized(rssDataItemLis) {
|
||||
if (rssDataItemLis.isNotEmpty() && rssDataItemLis.size > position) {
|
||||
try {
|
||||
val rssData = rssDataItemLis.get(position)
|
||||
if (rssData.pubDate() > 1000L) {
|
||||
holder.view.date.text = dateFormat.format(Date(rssData.pubDate()))
|
||||
if (rssDataItemLis.isNotEmpty() && rssDataItemLis.size > position) {
|
||||
val rssData = rssDataItemLis[position]
|
||||
if (rssData.pubDate() > 1000L) {
|
||||
holder.view.date.text = dateFormat.format(Date(rssData.pubDate()))
|
||||
} else {
|
||||
holder.view.date.text = emptyDate
|
||||
}
|
||||
|
||||
|
||||
holder.view.title.text = "".plus(if (rssData.vote) " * " else "")
|
||||
.plus(rssData.title().plus("[R:${rssData.read}]"))
|
||||
holder.view.desc.text = rssData.description()
|
||||
|
||||
var param = holder.view.circlePreview.layoutParams
|
||||
holder.view.circlePreview.layoutParams =
|
||||
ConstraintLayout.LayoutParams(rssData.category().defaultImgSize(), param.height)
|
||||
holder.view.circlePreview.visibility = rssData.category().getDefaultVisibiliy()
|
||||
Picasso.get().cancelRequest(holder.view.circlePreview)
|
||||
|
||||
if (rssData.thumbnailUrl()?.length ?: 0 > 6) {
|
||||
Picasso.get().load(rssData.thumbnailUrl().replace("&", "&").toUri())
|
||||
.into(holder.view.circlePreview)
|
||||
} else if (rssData.category().getResId() > 0) {
|
||||
holder.view.circlePreview.setImageResource(rssData.category().getResId())
|
||||
} else {
|
||||
holder.view.circlePreview.setImageDrawable(null)
|
||||
}
|
||||
|
||||
holder.itemView.tag = rssData
|
||||
holder.itemView.setOnClickListener(dateViewClick)
|
||||
holder.itemView.setOnTouchListener(object : View.OnTouchListener {
|
||||
override fun onTouch(
|
||||
v: View,
|
||||
event: MotionEvent
|
||||
): Boolean {
|
||||
if (event.device != null && event.device.name != null && (event.device.name?.contains(
|
||||
"JX-12",
|
||||
true
|
||||
) == true || event.device.name?.equals("J06", true) == true)
|
||||
) {
|
||||
Blog.LOGE("event.device.name >>> ${event.device.name}")
|
||||
return true//mSimpleFingerGestures.onTouch(v,event)
|
||||
} else {
|
||||
holder.view.date.text = emptyDate
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
holder.view.title.text = "".plus(if (rssData.vote) " * " else "")
|
||||
.plus(rssData.title().plus("[R:${rssData.read}]"))
|
||||
holder.view.desc.text = rssData.description()
|
||||
|
||||
var param = holder.view.circlePreview.layoutParams
|
||||
holder.view.circlePreview.layoutParams =
|
||||
ConstraintLayout.LayoutParams(rssData.category().defaultImgSize(), param.height)
|
||||
holder.view.circlePreview.visibility = rssData.category().getDefaultVisibiliy()
|
||||
Picasso.get().cancelRequest(holder.view.circlePreview)
|
||||
|
||||
if (rssData.thumbnailUrl()?.length ?: 0 > 6) {
|
||||
Picasso.get().load(rssData.thumbnailUrl().replace("&", "&").toUri())
|
||||
.into(holder.view.circlePreview)
|
||||
} else if (rssData.category().getResId() > 0) {
|
||||
holder.view.circlePreview.setImageResource(rssData.category().getResId())
|
||||
} else {
|
||||
holder.view.circlePreview.setImageDrawable(null)
|
||||
}
|
||||
|
||||
holder.itemView.tag = rssData
|
||||
holder.itemView.setOnClickListener(dateViewClick)
|
||||
holder.itemView.setOnTouchListener(object : View.OnTouchListener {
|
||||
override fun onTouch(
|
||||
v: View,
|
||||
event: MotionEvent
|
||||
): Boolean {
|
||||
if (event.device != null && event.device.name != null && (event.device.name?.contains(
|
||||
"JX-12",
|
||||
true
|
||||
) == true || event.device.name?.equals("J06", true) == true)
|
||||
) {
|
||||
Blog.LOGE("event.device.name >>> ${event.device.name}")
|
||||
return true//mSimpleFingerGestures.onTouch(v,event)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
// v.setOnLongClickListener {
|
||||
// WorkersDb.getRealm().apply {
|
||||
// copyFromRealm(rss)
|
||||
// }
|
||||
// }
|
||||
holder.itemView.setOnLongClickListener(mLongClickListener)
|
||||
} catch (e: Exception){}
|
||||
|
||||
}
|
||||
holder.itemView.setOnLongClickListener(mLongClickListener)
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,8 +268,7 @@ internal class RssItemAdapter (
|
||||
rssDataItemLis.clear()
|
||||
rssDataItemLis.addAll(newList)
|
||||
}
|
||||
|
||||
notifyDataSetChanged()
|
||||
notifyDataSetChanged()
|
||||
|
||||
// CoroutineScope(Dispatchers.IO).launch {
|
||||
// rssList.clear()
|
||||
|
||||
@ -22,57 +22,57 @@ class ArcaGetter : BaseGetter {
|
||||
}
|
||||
|
||||
override fun realWork(): Result {
|
||||
// RssDataType.ARCA.isOn {
|
||||
// try {
|
||||
// Blog.LOGE("realWork() ${this::class.simpleName}")
|
||||
// temp.clear()
|
||||
// val urls = arrayListOf(
|
||||
// "https://arca.live/b/singbung?mode=best",
|
||||
//// "https://arca.live/b/headline",
|
||||
//// "https://arca.live/b/live",
|
||||
// "https://arca.live/b/namuhotnow",
|
||||
// "https://arca.live/b/society",
|
||||
//// "https://arca.live/b/replay",
|
||||
//// "https://arca.live/b/breaking"
|
||||
// )
|
||||
// urls.forEach {
|
||||
//// try {
|
||||
//// Jsoup.connect(it)
|
||||
//// .userAgent(USAGT)
|
||||
//// .header("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
|
||||
//// .header("accept-language", "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7")
|
||||
//// .header("cache-control", "no-cache")
|
||||
//// .header("pragma", "no-cache")
|
||||
//// .ignoreContentType(true)
|
||||
//// .timeout(5000)
|
||||
//// .get().let { arca ->
|
||||
////// BLog.LOGE("url >> ${it} >> ${arca}")
|
||||
//// arca.getElementsByClass("vrow hybrid").forEach { araca_li ->
|
||||
//// if (araca_li.html().contains("title ") == true) {
|
||||
//// parseArcaLi(araca_li).apply {
|
||||
//// this.forEach {
|
||||
//// if (it.pubDate() > commicsDateTime) {
|
||||
//// temp.add(it.getRssData())
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// } catch (e : Exception) {
|
||||
//// e.printStackTrace()
|
||||
//// }
|
||||
//
|
||||
// }
|
||||
//// Jsoup.connect("https://projrctjav.com").userAgent(USAGT).get().let { projectj ->
|
||||
//// BLog.LOGE("projectj >>>>> ${projectj}")
|
||||
//// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
RssDataType.ARCA.isOn {
|
||||
try {
|
||||
Blog.LOGE("realWork() ${this::class.simpleName}")
|
||||
temp.clear()
|
||||
val urls = arrayListOf(
|
||||
"https://arca.live/b/singbung?mode=best",
|
||||
// "https://arca.live/b/headline",
|
||||
// "https://arca.live/b/live",
|
||||
"https://arca.live/b/namuhotnow",
|
||||
"https://arca.live/b/society",
|
||||
// "https://arca.live/b/replay",
|
||||
// "https://arca.live/b/breaking"
|
||||
)
|
||||
urls.forEach {
|
||||
try {
|
||||
Jsoup.connect(it)
|
||||
.userAgent(USAGT)
|
||||
.header("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
|
||||
.header("accept-language", "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7")
|
||||
.header("cache-control", "no-cache")
|
||||
.header("pragma", "no-cache")
|
||||
.ignoreContentType(true)
|
||||
.timeout(5000)
|
||||
.get().let { arca ->
|
||||
// BLog.LOGE("url >> ${it} >> ${arca}")
|
||||
arca.getElementsByClass("vrow hybrid").forEach { araca_li ->
|
||||
if (araca_li.html().contains("title ") == true) {
|
||||
parseArcaLi(araca_li).apply {
|
||||
this.forEach {
|
||||
if (it.pubDate() > commicsDateTime) {
|
||||
temp.add(it.getRssData())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
// Jsoup.connect("https://projrctjav.com").userAgent(USAGT).get().let { projectj ->
|
||||
// BLog.LOGE("projectj >>>>> ${projectj}")
|
||||
// }
|
||||
// }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
return Result.success().apply {
|
||||
// WorkersDb.insertBulkData(temp)
|
||||
WorkersDb.insertBulkData(temp)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,6 @@ import io.realm.kotlin.query.RealmQuery
|
||||
import io.realm.kotlin.query.Sort
|
||||
import io.realm.kotlin.types.BaseRealmObject
|
||||
import io.realm.kotlin.types.TypedRealmObject
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
@ -105,32 +104,34 @@ object WorkersDb {
|
||||
|
||||
// val blockKeyword = arrayListOf<String>("붕괴 스타레일","붕괴 스타일","트릭컬 RE:VIVE","원신","메이플스토리","")
|
||||
fun insertBulkData(rssDatas: Collection<RssData>) {
|
||||
try {
|
||||
getRealm().writeBlocking {
|
||||
try {
|
||||
rssDatas.forEach { t ->
|
||||
var results= query<RssData>("originPage == $0", t.originPage).find()
|
||||
if (results.isEmpty()) {
|
||||
if(t.category().equals(RssDataType.PRIVATE)) {
|
||||
t.pubDate = afterDay(t.pubDate)
|
||||
rssDatas.forEach {
|
||||
try {
|
||||
getRealm().writeBlocking {
|
||||
try {
|
||||
rssDatas.forEach { t ->
|
||||
var results= query<RssData>("originPage == $0", t.originPage).find()
|
||||
if (results.isEmpty()) {
|
||||
if(it.category().equals(RssDataType.PRIVATE)) {
|
||||
it.pubDate = afterDay(it.pubDate)
|
||||
}
|
||||
this.copyToRealm(t, UpdatePolicy.ERROR)
|
||||
} else {
|
||||
if(it.category().equals(RssDataType.PRIVATE)) {
|
||||
it.pubDate = afterDay(it.pubDate)
|
||||
it.vote = results.first().vote
|
||||
it.read = results.first().read
|
||||
this.copyToRealm(t, UpdatePolicy.ALL)
|
||||
}
|
||||
}
|
||||
this.copyToRealm(t, UpdatePolicy.ALL)
|
||||
} else {
|
||||
if(t.category().equals(RssDataType.PRIVATE)) {
|
||||
t.pubDate = afterDay(t.pubDate)
|
||||
}
|
||||
t.vote = results.first().vote
|
||||
t.read = results.first().read
|
||||
this.copyToRealm(t, UpdatePolicy.ALL)
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
} catch (e : Exception) {
|
||||
|
||||
}
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -53,20 +53,6 @@
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_height="40dp"
|
||||
/>
|
||||
<ImageButton
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/hide"
|
||||
android:id="@+id/share"
|
||||
android:scaleType="fitCenter"
|
||||
android:adjustViewBounds="true"
|
||||
android:visibility="visible"
|
||||
android:background="@null"
|
||||
android:tint="@color/white"
|
||||
android:foregroundTint="@color/white"
|
||||
android:src="@drawable/ic_share"
|
||||
android:layout_width="40dp"
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_height="40dp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/home"
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
android:textColor="@color/black"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:id="@+id/private_mode"
|
||||
android:id="@+id/parivate_mode"
|
||||
android:checked="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user