Files
ReplyAutoV1---WIP/B4A/Subs.bas
2023-09-24 03:29:06 -06:00

1092 lines
60 KiB
QBasic

B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=StaticCode
Version=11
@EndOfDesignText@
'Code module
'Subs in this code module will be accessible from all modules.
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
' Public GZip As GZipStrings 'Usa la libreria CompressStrings
Private su As StringUtils 'Usa la libreria StringUtils
Dim phn As Phone
Dim devModel As String
Dim kmt, errorLog As SQL 'Requiere la libreria "SQL" 'ignore
' Dim wifi As MLwifi
Dim ssid As String 'ignore
' Dim rutaInicioHoy As String = ""
End Sub
'Pone el valor de phn.Model en la variable global "devModel"
Sub getPhnId As String 'ignore
'Requiere la libreria "Phone"
devModel = phn.Model
If devModel.Length <= 3 Then 'Si phn.Model esta en blanco ...
Dim t As String = phn.GetSettings("android_id") 'Intentamos con "android_id"
devModel = t
End If
If devModel.Length >= 3 Then 'Si tenemos valor para phn.Model
File.WriteString(File.DirInternal, "phnId.txt", devModel) 'Sobreescribimos archivo phnId.txt with deviceId
' Log("Tenemos phnId: "&devModel&" "&File.DirInternal&"/phn.txt sobreescrito")
Else If devModel.Length < 3 Then ' Si no tenemos valor, lo leemos de phnId.txt
Dim s As String = File.ReadString(File.DirInternal, "phnId.txt")
devModel = s
' Log("Leemos id de "&File.DirInternal&"/phnId.txt")
' Log(devModel)
End If
Return devModel
End Sub
'Comprime y regresa un texto (str) en base64
Sub compress(str As String) As String 'ignore
'Requiere la libreria "CompressStrings"
' Dim compressed() As Byte = GZip.compress(str)
' Dim base64 As String = su.EncodeBase64(compressed)
' Log($"Comprimido: ${base64.Length}"$)
' Return base64
End Sub
'Descomprime y regresa un texto en base64
Sub decompress(base64 As String) As String 'ignore
Dim decompressedbytes() As Byte = su.DecodeBase64(base64)
' Log($"decompressedbytesLength: ${decompressedbytes.Length}"$)
Dim bc As ByteConverter
Dim uncompressed As String = bc.StringFromBytes(decompressedbytes,"UTF8")
If Starter.logger Then Log($"Descomprimido: ${uncompressed.Length}"$)
' Log($"Decompressed String = ${uncompressed}"$)
Return uncompressed
End Sub
'Convierte una fecha al formato yyMMddHHmmss
Sub fechaKMT(fecha As String) As String 'ignore
' Log(fecha)
Dim OrigFormat As String = DateTime.DateFormat 'save orig date format
DateTime.DateFormat="yyMMddHHmmss"
Dim nuevaFecha As String=DateTime.Date(fecha)
DateTime.DateFormat=OrigFormat 'return to orig date format
' Log(nuevaFecha)
Return nuevaFecha
End Sub
'Genera una notificacion con importancia alta
Sub notiHigh(title As String, body As String, activity As Object) 'ignore
Private notif As Notification
notif.Initialize2(notif.IMPORTANCE_HIGH)
notif.Icon = "icon"
notif.Vibrate = False
notif.Sound = False
notif.AutoCancel = True
If Starter.logger Then Log("notiHigh: "&title)
notif.SetInfo(title, body, activity)
' Log("notiHigh SetInfo")
notif.Notify(777)
End Sub
'Regresa el objeto de una notificacion con importancia baja
Sub notiLowReturn(title As String, Body As String, id As Int) As Notification 'ignore
Private Notification As Notification
Notification.Initialize2(Notification.IMPORTANCE_LOW)
If Starter.logger Then Log("notiLowReturn: "&title)
Notification.Icon = "icon"
Notification.Sound = False
Notification.Vibrate = False
Notification.SetInfo(title, Body, Main)
Notification.Notify(id)
' Log("notiLowReturn SetInfo")
Return Notification
End Sub
'Escribimos las coordenadas y fecha a un archivo de texto
Sub guardaInfoEnArchivo(coords As String) 'ignore
' Cambiamos el formato de la hora
Dim OrigFormat As String=DateTime.DateFormat 'save orig date format
DateTime.DateFormat="MMM-dd HH:mm:ss"
Dim lastUpdate As String=DateTime.Date(DateTime.Now)
DateTime.DateFormat=OrigFormat 'return to orig date format
Dim ubic As String = coords&","&lastUpdate
Dim out As OutputStream = File.OpenOutput(File.DirRootExternal, "gps.txt", True)
Dim s As String = ubic & CRLF
Dim t() As Byte = s.GetBytes("UTF-8")
out.WriteBytes(t, 0, t.Length)
out.Close
End Sub
'Escribimos las coordenadas (latitud, longitud, fecha) y fecha a una BD
Sub guardaInfoEnBD(coords As String) 'ignore
If Starter.logger Then Log("Guardamos ubicacion en BD - "&coords)
Try
Dim latlon() As String = Regex.Split("\|", coords)
If latlon.Length < 2 Then latlon = Regex.Split(",", coords) 'Si son menos de 2, entonces estan separadas por comas y no por "|"
' If Main.Logger Then Log("LatLon="&latlon)
If Not(kmt.IsInitialized) Then revisaBD
kmt.ExecNonQuery2("INSERT INTO RUTA_GPS(fecha, lat, lon) VALUES (?,?,?)", Array As Object (latlon(2),latlon(0),latlon(1)))
Catch
Log(LastException)
End Try
End Sub
'Limpiamos la tabla RUTA_GPS de la BD
Sub deleteGPS_DB 'ignore
kmt.ExecNonQuery("delete from RUTA_GPS")
kmt.ExecNonQuery("vacuum;")
End Sub
'Limpiamos la tabla errorLog de la BD
Sub deleteErrorLog_DB 'ignore
If Not(errorLog.IsInitialized) Then revisaBD
errorLog.ExecNonQuery("delete from errores")
errorLog.ExecNonQuery("vacuum;")
' ToastMessageShow("Borrada", False)
End Sub
'Borramos el archio "gps.txt"
Sub borramosArchivoGPS 'ignore
Dim out As OutputStream = File.OpenOutput(File.DirRootExternal, "gps.txt", False)
Dim s As String = ""
Dim t() As Byte = s.GetBytes("UTF-8")
out.WriteBytes(t, 0, t.Length)
out.Close
End Sub
'Revisa que exista la BD y si es necesario crea algunas tablas dentro de ella
Sub revisaBD 'ignore
' Log("subs.revisaBD")
Starter.ruta = File.DirInternal
If Not(Starter.colaNotifs.IsInitialized) Then Starter.colaNotifs.Initialize(Starter.ruta, "colaNotifs.db", True)
Starter.colaNotifs.ExecNonQuery("CREATE TABLE If Not EXISTS cola (id INTEGER UNIQUE, numero TEXT, contestada INTEGER, timestamp INTEGER, PRIMARY KEY(id AUTOINCREMENT))")
'Tabla para la reglas
If Not(Starter.reglasDB.IsInitialized) Then Starter.reglasDB.Initialize(Starter.ruta, "bow.db", True)
If Starter.logger Then LogColor("========"&Starter.ruta, Colors.Red)
Starter.reglasDB.ExecNonQuery("CREATE TABLE If Not EXISTS reglas (id INTEGER UNIQUE, nombre TEXT, activa INTEGER, recibe TEXT, contesta TEXT, destinatario TEXT, contactosSI TEXT, PRIMARY KEY(id AUTOINCREMENT))")
'Tabla para las imagenes
Starter.reglasDB.ExecNonQuery("CREATE TABLE If Not EXISTS datosImg (message_row_id INTEGER, chat_row_id INTEGER, autotransfer_retry_enabled INTEGER, media_job_uuid TEXT, transferred INTEGER, transcoded INTEGER, file_path TEXT, file_size INTEGER, suspicious_content INTEGER, trim_from INTEGER, trim_to INTEGER, face_x INTEGER, face_y INTEGER, media_key_timestamp INTEGER, width INTEGER, height INTEGER, has_streaming_sidecar INTEGER, gif_attribution INTEGER, thumbnail_height_width_ratio REAL, first_scan_length INTEGER, file_length INTEGER, media_name TEXT, file_hash TEXT, media_duration INTEGER, page_count INTEGER, enc_file_hash TEXT, is_animated_sticker INTEGER, mute_video INTEGER)")
Starter.reglasDB.ExecNonQuery("CREATE TABLE If Not EXISTS datosMsj (_id INTEGER, key_remote_jid TEXT, key_from_me INTEGER, key_id TEXT, status INTEGER, needs_push INTEGER, timestamp INTEGER, media_wa_type TEXT, media_size INTEGER, media_name TEXT, media_caption TEXT, media_hash TEXT, media_duration INTEGER, origin INTEGER, latitude REAL, longitude REAL, thumb_image TEXT, received_timestamp INTEGER, send_timestamp INTEGER, receipt_server_timestamp INTEGER, receipt_device_timestamp INTEGER, recipient_count INTEGER, quoted_row_id INTEGER, edit_version INTEGER, media_enc_hash TEXT, forwarded INTEGER, preview_type INTEGER, lookup_tables INTEGER, future_message_type INTEGER, message_add_on_flags INTEGER)")
'Tabla para la notificaciones
If Not(Starter.historicoDB.IsInitialized) Then Starter.historicoDB.Initialize(Starter.ruta, "historicoDB.db", True)
Starter.historicoDB.ExecNonQuery("CREATE TABLE If Not EXISTS historico (id INTEGER UNIQUE, numero TEXT, nombre TEXT, regla TEXT, mensaje TEXT, E_S TEXT, clic TEXT, fecha TEXT, PRIMARY KEY(id AUTOINCREMENT))")
'Tabla para la bitacora de errores
If Not(errorLog.IsInitialized) Then errorLog.Initialize(Starter.ruta, "errores.db", True)
errorLog.ExecNonQuery("CREATE TABLE IF NOT EXISTS errores(fecha INTEGER, error TEXT)")
Try 'Intentamos usar "pragma_table_info" para revisar si existe la columna "numero" en la tabla
Dim c As Cursor=Starter.historicoDB.ExecQuery("SELECT COUNT(*) AS fCol FROM pragma_table_info('historico') WHERE name='numero'")
c.Position = 0
If c.GetString("fCol") = 0 Then 'Si no esta la columna FECHA la agregamos
Starter.historicoDB.ExecNonQuery("ALTER TABLE historico ADD COLUMN numero TEXT")
End If
Catch 'Si no funciona "pragma_table_info" lo hacemos con try/catch
Try
Starter.historicoDB.ExecNonQuery("ALTER TABLE historico ADD COLUMN numero TEXT")
Catch
Log(LastException)
End Try
End Try
Try 'Intentamos usar "pragma_table_info" para revisar si existe la columna "regla" en la tabla
Dim c As Cursor=Starter.historicoDB.ExecQuery("SELECT COUNT(*) AS fCol FROM pragma_table_info('historico') WHERE name='regla'")
c.Position = 0
If c.GetString("fCol") = 0 Then 'Si no esta la columna FECHA la agregamos
Starter.historicoDB.ExecNonQuery("ALTER TABLE historico ADD COLUMN regla TEXT")
End If
Catch 'Si no funciona "pragma_table_info" lo hacemos con try/catch
Try
Starter.historicoDB.ExecNonQuery("ALTER TABLE historico ADD COLUMN regla TEXT")
Catch
Log(LastException)
End Try
End Try
End Sub
'Obtiene el ssid al que esta conectado el telefono
Sub getSSID 'ignore
' 'Requiere la libreria "MLWifi400"
' If wifi.isWifiConnected Then
' ssid = wifi.WifiSSID
' End If
End Sub
'Convierte un texto en formato JSON a un objeto "Map"
Sub JSON2Map(theJson As String) As Map 'ignore
'Requiere la libreria "JSON"
Try
Private json As JSONParser
json.Initialize(theJson)
Return json.NextObject
Catch
Log(LastException)
log2DB("JSON2Map: "&LastException)
Private m As Map = CreateMap("title":"Error generating JSON", "t":"Error", "Message":LastException, "text" : LastException)
Return m
End Try
End Sub
'Convierte un mapa a formato JSON
Sub map2JSON(m As Map) As String 'ignore
'Requiere la libreria "JSON"
'Convierte un objecto "Map" a JSON
Dim jg As JSONGenerator
jg.Initialize(m)
Dim t As String = jg.ToString
Return t
End Sub
'Mandamos "coords" en un mensaje a "Sprvsr"
Sub mandamosLoc(coords As String) 'ignore
'' Log("Iniciamos mandamosLoc "&coords)
'' Log("locRequest="&Tracker.locRequest)
' guardaInfoEnBD(coords)'Escribimos coordenadas y fecha a una bd
' Dim t As String
' If Tracker.locRequest="Activa" Then
' If PushService.au = 1 Then
' t = "au" ' es una actualizacion
' Else
' t = "u" ' es una peticion
' End If
' Dim params As Map = CreateMap("topic":"Sprvsr", "coords":coords, "t":t, "b":PushService.battery)
' CallSub2(PushService, "mandaMensaje",params)
' Tracker.locRequest="Enviada"
' CallSubDelayed(Tracker,"CreateLocationRequest")
' End If
End Sub
'Regresa la fecha y hora de hoy a las 00:00 en el formato "yyMMddHHMMSS"
Sub fechaInicioHoy As String 'ignore
Dim OrigFormat As String = DateTime.DateFormat 'save orig date format
DateTime.DateFormat="yyMMdd"
Private h As String = DateTime.Date(DateTime.Now)&"000000"
DateTime.DateFormat=OrigFormat 'return to orig date format
If Starter.logger Then Log("Hoy="&h)
Return h
End Sub
'Guardamos "texto" a la bitacora
Sub log2DB(texto As String) 'ignore
LogColor(fechaKMT(DateTime.Now)&" - log2BD: '"&texto&"'", Colors.Magenta)
If kmt.IsInitialized Then kmt.ExecNonQuery2("INSERT INTO bitacora(fecha, texto) VALUES (?,?)", Array As Object (fechaKMT(DateTime.now), texto))
End Sub
'Regresa verdadero si ya pasaron XX minutos de la fecha dada
Sub masDeXXMins(hora As Int, mins As Int) As Boolean 'ignore
If (hora + mins * DateTime.TicksPerMinute) < DateTime.Now Then
Return True
Else
Return False
End If
End Sub
'Regresa verdadero si ya pasaron XX minutos de la fechaKMT dada
Sub masDeXXMinsKMT(hora As String, mins As Int) As Boolean 'ignore
Try
' LogColor($"Hora=${fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute)}, Mins=${mins}, Actual=${fechaKMT(DateTime.Now)}"$,Colors.red)
If fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute < DateTime.Now Then
' Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " < " & fechaKMT(DateTime.Now))
Return True
Else
' Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " > " & fechaKMT(DateTime.Now))
Return False
End If
Catch
Log(LastException)
End Try
End Sub
'Limpiamos la tabla "bitacora" de la BD
Sub borraLogDB 'ignore
If Starter.logger Then LogColor("Borramos BD de log", Colors.Magenta)
kmt.ExecNonQuery("delete from bitacora")
kmt.ExecNonQuery("vacuum;")
End Sub
'Borramos renglones extra de la tabla de errores
Sub borraArribaDe100Errores 'ignore
If Not(errorLog.IsInitialized) Then revisaBD
If Starter.logger Then LogColor("Recortamos la tabla de Errores, limite de 100", Colors.Magenta)
errorLog.ExecNonQuery("DELETE FROM errores WHERE fecha NOT in (SELECT fecha FROM errores ORDER BY fecha desc LIMIT 99 )")
errorLog.ExecNonQuery("vacuum;")
' Log("Borramos mas de 100 de errorLog")
End Sub
'Borramos renglones extra de la tabla de bitacora
Sub borraArribaDe600RenglonesBitacora 'ignore
revisaBD
If Starter.logger Then LogColor("Recortamos la tabla de la Bitacora, limite de 600", Colors.Magenta)
Private c As Cursor
c = kmt.ExecQuery("select fecha from bitacora")
c.Position = 0
If c.RowCount > 650 Then
kmt.ExecNonQuery("DELETE FROM bitacora WHERE fecha NOT in (SELECT fecha FROM bitacora ORDER BY fecha desc LIMIT 599 )")
kmt.ExecNonQuery("vacuum;")
' Log("Borramos mas de 600 de bitacora")
End If
c.Close
End Sub
'Inserta 50 renglones de prueba a la tabla "errores"
Sub insertaRenglonesPruebaEnErrorLog 'ignore
If Not(errorLog.IsInitialized) Then revisaBD
If Starter.logger Then Log("insertamos 50 renglones a errorLog")
For x = 1 To 50
errorLog.ExecNonQuery2("INSERT INTO errores(fecha, error) VALUES (?,?)", Array As Object (fechaKMT(DateTime.now), "abc"))
If Starter.logger Then Log(x)
Next
End Sub
'Regresa la tabla "errores" en una lista de mapas convertida a JSON
Sub dameErroresJSON(SQL As SQL, maxErrores As Int, comprimido As Boolean) As String 'ignore
If Starter.logger Then Log("dameErroresJSON")
Private j As JSONGenerator
Private lim As String
Private cur As ResultSet
Private l As List
Private i As Int = 0
l.Initialize
Dim m, m2 As Map
m2.Initialize
If maxErrores = 0 Then lim = "" Else lim = "limit "&maxErrores
cur = SQL.ExecQuery("select * from errores order by fecha desc "&lim)
Do While cur.NextRow
m.Initialize
m.Put("fecha", cur.GetString("fecha"))
m.Put("error", cur.GetString("error"))
m2.Put(i,m)
i = i + 1
Loop
cur.Close
j.Initialize(m2)
Log(j.ToString)
If comprimido Then
Return compress(j.ToString)
Else
Return j.ToString
End If
End Sub
'Convierte una fecha en formato YYMMDDHHMMSS a Ticks
Sub fechaKMT2Ticks(fKMT As String) As Long 'ignore
Try
If fKMT.Length = 12 Then
Private parteFecha As String = fKMT.SubString2(0,6)
Private parteHora As String = fKMT.SubString(6)
Private OrigFormat As String = DateTime.DateFormat 'save original date format
DateTime.DateFormat="yyMMdd"
DateTime.TimeFormat="HHmmss"
Private ticks As Long = DateTime.DateTimeParse(parteFecha,parteHora)
' Log(" +++ +++ pFecha:"&parteFecha&" | pHora:"&parteHora)
DateTime.DateFormat=OrigFormat 'return to original date format
Return ticks
Else
If Starter.logger Then Log("Formato de fecha incorrecto, debe de ser 'yyMMddHHmmss', no '"&fKMT&"' largo="&fKMT.Length)
Return 0
End If
Catch
Log(LastException)
If Starter.logger Then LogColor($"Fecha dada: ${fKMT}, Parte Fecha: ${parteFecha}, Parte Hora: ${parteHora}"$, Colors.Red)
Return 0
End Try
End Sub
Sub InstallAPK(dir As String, apk As String) 'ignore
' If File.Exists(dir, apk) Then
' Dim i As Intent
' i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(dir, apk))
' i.SetType("application/vnd.android.package-archive")
' StartActivity(i)
' End If
End Sub
'Hace visible el panel con los parametros "Top" y "Left" dados
Sub panelVisible(panel As Panel, top As Int, left As Int) 'ignore
panel.BringToFront
panel.Visible = True
panel.Top = top
panel.Left = left
End Sub
'Oculta el panel especificado y lo manda al fondo
Sub panelOculto(panel As Panel) 'ignore
panel.SendToBack
panel.Visible = False
End Sub
'Centra una etiqueta dentro de un elemento superior
Sub centraEtiqueta(elemento As Label, anchoElementoSuperior As Int) 'ignore
elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2)
End Sub
'Centra un panel dentro de un elemento superior
Sub centraPanel(elemento As Panel, anchoElementoSuperior As Int) 'ignore
elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2)
End Sub
'Centra una barra de progreso dentro de un elemento superior
Sub centraProgressBar(elemento As ProgressBar, anchoElementoSuperior As Int) 'ignore
elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2)
End Sub
Sub insertaEnErrores(error As String) 'ignore
If Not(errorLog.IsInitialized) Then revisaBD
errorLog.ExecNonQuery2("INSERT INTO errores(fecha, error) VALUES (?,?)", Array As Object (fechaKMT(DateTime.now), error))
End Sub
'Cierra todas las actividades y sale de la aplicacion (Android 4.1+ - API 16+)
Sub cierraActividades 'ignore
If Starter.logger Then Log("closing activities")
Dim jo As JavaObject
jo.InitializeContext
jo.RunMethod("finishAffinity", Null)
End Sub
'Regresa un mapa con las reglas.
Sub traeReglas As Map
If Starter.logger Then LogColor("Traemos reglas de BD", Colors.Magenta)
Private mReglas As Map
mReglas.Initialize
Private c As Cursor
' c=Starter.reglasDB.ExecQuery("select * from reglas order by nombre")
c=Starter.reglasDB.ExecQuery("Select *, SUBSTR(nombre, (INSTR(nombre, '_')+1), (LENGTH(nombre)-INSTR(nombre, '_'))) as ord FROM reglas order by ord") 'Este query trae las reglas ordenadas por "nombre" que tienen texto como "1.1.2, 10.2.1, 13.1"
If c.RowCount > 0 Then
Private mr As Map
For i=0 To c.RowCount -1
c.Position = i
Private contactosSI As String = c.GetString("contactosSI")
If contactosSI = Null Then contactosSI = ""
mr = CreateMap("activa":c.GetInt("activa"), "recibe":c.GetString("recibe"), "contesta":c.GetString("contesta"), "id":c.GetInt("id"), "nombre":c.GetString("nombre"), "destinatario":c.GetString("destinatario"), "contactoEspecifico":contactosSI)
mReglas.Put(c.GetInt("id"), mr)
Next
End If
c.Close
' LogColor("mReglas=" & mReglas, Colors.Blue)
Return mReglas
End Sub
'Activa o desactiva la regla especificada.
Sub guardaRegla(id As Int, activa As Boolean)
' Private c As Cursor
Private act As Int = 0
If activa Then act = 1
If Starter.logger Then Log("Guardamos regla " & id)
If Starter.logger Then Log($"update reglas set activa=${act} where id=${id}"$)
Starter.reglasDB.ExecNonQuery($"update reglas set activa=${act} where id=${id}"$)
End Sub
'Agrega una regla en blanco y descativada a la base de datos.
Sub agregaRegla
Starter.reglasDB.ExecNonQuery("insert into reglas (activa, recibe, contesta) values (0, '', '')")
Dim c As Cursor
c=Starter.reglasDB.ExecQuery("select last_insert_rowid() as ultimo from reglas") 'Traemos el id de la ultima regla agregada.
If c.RowCount > 0 Then
c.Position = 0
Starter.reglasDB.ExecNonQuery($"update reglas set nombre = ${c.GetInt("ultimo")} where id = ${c.GetInt("ultimo")}"$) 'Y lo ponemos en el nombre.
End If
End Sub
'Borra una regla de la base de datos.
Sub borrarRegla (id As Int)
Starter.reglasDB.ExecNonQuery($"delete from reglas where id=${id}"$)
Starter.reglasDB.ExecNonQuery("delete from sqlite_sequence where name='reglas'")
Starter.reglasDB.ExecNonQuery("vacuum;")
End Sub
'Guarda el objeto de la notificacion en un mapa y en la cola de notificaciones por contestar.
Sub guardaNotificacion(sbn As StatusBarNotification) 'ignore
If Starter.logger Then Log("guardaNotificacion=" & sbn.Title & " - " & sbn.Message)
Private noti As lasNotis
noti.Initialize
noti.numero = sbn.Title
noti.notif = sbn
Dim titulo As String = sbn.Title
If isGroupWA(sbn) Then titulo = getGroupName2(sbn)
Private tempMap As Map
tempMap.Initialize
Private timestamp = DateTime.Now
tempMap.Put(titulo, noti)
NotificationService.notisMap2.Put(titulo, tempMap)
Starter.notismap2 = NotificationService.notisMap2
NotificationService.notificacionesPorContestar.Add(tempMap)'Tambien lo agregamos a la cola de notificaciones por contestar.
If Starter.logger Then LogColor("======== Notificaciones pendientes:" & NotificationService.notificacionesPorContestar.Size & "=============", Colors.Magenta)
' LogColor("Cola de notificaciones="&NotificationService.notificacionesPorContestar, Colors.RGB(168,0,0))
End Sub
'Searches the provided notification object for the string "@g.us" and if found returns TRUE.
Sub isGroupWA(sbn As StatusBarNotification) As Boolean
Private a As Boolean = False
If sbn.As(String).IndexOf("@g.us") > -1 Then a = True 'ignore
Return a
End Sub
'Returns the name of the group from the given notification object.
'Searches the provided notification for the string "hiddenConversationTitle" and if found, gets the name.
'If it is not a group returns the notification's title.
Sub getGroupName2(sbn As StatusBarNotification) As String
Private inicio As Int = sbn.Extras.As(String).IndexOf("hiddenConversationTitle=") 'ignore
If inicio > -1 And sbn.Extras.As(String).IndexOf("hiddenConversationTitle=null") = -1 Then 'ignore
Private x As String = sbn.Extras.As(String) 'ignore
Private fin As Int = x.IndexOf(", android.reduced.images=")
x = x.SubString2(inicio+24, fin)
x = Regex.Replace(" \(.+\)", x, "") 'Replace anything between () with "", this en the case that we have something like "MyGroupName (5 messages)"
Else 'Is not from a group.
Private x As String = sbn.Title
End If
Return x
End Sub
'Guarda la ultima regla que se haya cumplido y el número que la mandó.
Sub guardaUltimaRegla(sbn As StatusBarNotification, regla As String) 'ignore
Private numRemitente As String = getNumberWA(sbn)
If numRemitente = "Not a person" Then numRemitente = getGroupName(sbn.Title)
Private tmpMap As Map
tmpMap.Initialize
If NotificationService.histReglas.ContainsKey(numRemitente) Then tmpMap = NotificationService.histReglas.Get(numRemitente)
' Log("+++++++++++++++++++++++++++++++++++++++++++")
' Log(numRemitente)
' LogColor("histReglas="&NotificationService.histReglas,Colors.Blue)
' Log(regla)
' Log("tmpMap="&tmpMap)
Private tmpList, tmpList2 As List
tmpList.Initialize
tmpList2.Initialize
If tmpMap.ContainsKey("historico") Then tmpList = tmpMap.Get("historico")
If tmpMap.ContainsKey("histReglas") Then tmpList2 = tmpMap.Get("histReglas")
' Log(regla)
Private ur As String = ""
If tmpList.Size > 0 And tmpList.Get(0).As(Map).Size > 0 Then ur = tmpList.Get(0).As(Map).Get("regla")
' Log("Regla anterior: "&ur)
' LogColor(tmpList, Colors.red)
Private tm As Map = CreateMap("regla":regla, "mensaje":sbn.Message, "anterior":ur, "numero":numRemitente)
tmpList2.InsertAt(0, regla)
' LogColor("ponemos en historico:"&tm, Colors.Magenta)
tmpList.InsertAt(0, tm)
' Log(tm)
tmpMap = CreateMap("histReglas":tmpList2, "historico":tmpList, "numero":numRemitente)
' Log(tmpMap)
NotificationService.histReglas.Put(numRemitente, tmpMap)
' Starter.ultimaReglaCumplida.Put(numRemitente, tmpMap)
' Log(NotificationService.histReglas)
' Log("+++++++++++++++++++++++++++++++++++++++++++++")
' For i = 0 To tmpList.Size -1
' Log(tmpList.Get(i))
' Next
' Log("histReglas="&NotificationService.histReglas)
End Sub
'Manda el procesamiento de la siguiente regla a la regla especificada.
Sub vamosA( sbn As StatusBarNotification, regla As String)
Private numRemitente As String = getNumberWA(sbn)
If numRemitente = "Not a person" Then numRemitente = getGroupName(sbn.Title)
Private tmpMap As Map
tmpMap.Initialize
If NotificationService.histReglas.ContainsKey(numRemitente) Then tmpMap = NotificationService.histReglas.Get(numRemitente)
Private tmpList, tmpList2 As List
tmpList.Initialize
tmpList2.Initialize
If tmpMap.ContainsKey("historico") Then tmpList = tmpMap.Get("historico")
If tmpMap.ContainsKey("histReglas") Then tmpList2 = tmpMap.Get("histReglas")
If Starter.logger Then Log(regla)
Private ur As String = "" 'ignore
If tmpList.Size > 0 And tmpList.Get(0).As(Map).Size > 0 Then ur = tmpList.Get(0).As(Map).Get("regla")
' Log("Regla anterior: "&ur)
' Private tm As Map = CreateMap("regla":regla, "mensaje":sbn.Message, "anterior":ur, "numero":numRemitente) 'ignore
tmpList2.InsertAt(0, regla)
' LogColor("ponemos en historico:"&tm, Colors.Magenta)
' tmpList.InsertAt(0, tm)
tmpMap = CreateMap("histReglas":tmpList2, "historico":tmpList, "numero":numRemitente)
NotificationService.histReglas.Put(numRemitente, tmpMap)
If Starter.logger Then Log("histReglas="&NotificationService.histReglas)
End Sub
'Returns the sender's number.
'Searches the provided notification object and gets the numbers between "shortcut=" and "@s.whatsapp.net".
Sub getNumberWA(sbn As StatusBarNotification) As String
Private a As Int = sbn.As(String).IndexOf("@s.whatsapp.net") 'ignore
If a > -1 Then
Private x As String = sbn.As(String) 'ignore
Private y As Int = x.IndexOf("shortcut=")
x = x.SubString2(y+9, a)
Else 'It is probably is a group.
x = "Not a person"
End If
Return x
End Sub
'Returns the name of the group from the given text.
'If it is not a group, then returns the notification's title.
Sub getGroupName(sbnTitle As String) As String 'ignore
Private a As Int = sbnTitle.IndexOf(": ")
Private x As String = sbnTitle
If a > -1 Then
Private b As String = sbnTitle.SubString2(0, a)
x = Regex.Replace(" \(.+\)", b, "")
End If
Return x
End Sub
'Copia la base de datos de las reglas a la tarjeta de memoria.
Sub copiaDB
Private theDir As String = ""
Try
File.MakeDir(File.DirRootExternal, "Bow2.0")
theDir = "/Bow2.0"
Catch
theDir = ""
End Try
If Starter.logger Then Log($"Origen:${Starter.ruta}, destino:${File.DirRootExternal}"$)
Try
File.Copy(File.DirInternal,"bow.db",File.DirRootExternal&theDir,"bow.db")
File.Copy(File.DirInternal,"historicoDB.db",File.DirRootExternal&theDir,"historicoDB.db")
ToastMessageShow("Listo, copiado a " & File.DirRootExternal&theDir & "/bow.db", False)
Catch
ToastMessageShow("No se pudo hacer la copia: "&LastException, True)
End Try
End Sub
'Actualiza una regla modificada.
Sub actualizaRegla(id As Int, nombre As String, recibe As String, contesta As String, destinatario As String, contactosSI As String)
Starter.reglasDB.ExecNonQuery2("update reglas set nombre = ?, recibe = ?, contesta = ?, destinatario = ?, contactosSI = ? where id = ?", Array As Object(nombre, recibe, contesta, destinatario, contactosSI, id))
If Starter.logger Then Log($"========== ${nombre}, ${recibe}, ${contesta}, ${id}, ${destinatario}, ${contactosSI}"$)
If Starter.logger Then Log("Guardado")
End Sub
'Regresa el "shortcut" del remitente.
'Si es de un grupo es algo como "120363023512345678@g.us"
'Si es de una persona entonces "5215512345678@s.whatsapp.net"
Sub getShortcut(sbn As StatusBarNotification) As String
Private x As String = sbn.As(String) 'ignore
Private ap As Int = x.IndexOf("@s.whatsapp.net") 'ignore
Private ag As Int = x.IndexOf("@g.us") 'ignore
Private sc As Int = x.IndexOf("shortcut=")
If x.IndexOf("Notification(channel=group") = -1 And x.IndexOf("Notification(channel=individual") = -1 And x.IndexOf("Notification(channel=silent") = -1 Then 'En algunos casos el "channel" trae el "shortcut" y estorba para en "indexOf".
sc = x.IndexOf("channel=") - 1
End If
If Starter.logger Then LogColor(x, Colors.red)
If ap > -1 Then
Private x As String = sbn.As(String) 'ignore
If Starter.logger Then Log($"x:${x}, y:${sc}, ag:${ap}"$)
x = x.SubString2(sc+9, ap+15)
Else if ag > -1 Then 'It is probably is a group.
Private x As String = sbn.As(String) 'ignore
If Starter.logger Then Log($"x:${x}, y:${sc}, ag:${ag}"$)
x = x.SubString2(sc+9, ag+5)
End If
Return x
End Sub
'Abre Whatsapp en el chat especificado.
Sub abreWAChat(chat As String)
' Dim num As String = "5215554192439@s.whatsapp.net"
' Dim grupo As String = "120363022847621622@g.us"
Dim i As Intent
i.Initialize("android.intent.action.SEND", "")
i.SetType("text/plain")
i.PutExtra("android.intent.extra.TEXT", " ")
i.PutExtra("jid", chat)
i.SetPackage("com.whatsapp")
StartActivity(i)
End Sub
'Regresa el numero de veces que aparece un caracter en la cadena dada.
'Esta funcion la ocupo para reconocer las reglas que dependen de otras (Submenus).
Sub CountChars(text As String, substr As String) As Int
Dim t As String = text.Replace(substr, "")
Return text.Length - t.Length
End Sub
'Change CheckBox colors
Sub SetButtonTintList(View As View, Disabled As Int, Enabled As Int)
Dim States(2,1) As Int
Dim sd As StateListDrawable 'ignore
States(0, 0) = sd.State_Enabled
States(1, 0) = sd.State_Disabled
Dim Color(2) As Int = Array As Int(Enabled, Disabled)
Dim CSL As JavaObject
CSL.InitializeNewInstance("android.content.res.ColorStateList",Array(States,Color))
Dim jo As JavaObject
jo.InitializeStatic("android.support.v4.widget.CompoundButtonCompat")
jo.RunMethod("setButtonTintList", Array(View, CSL))
End Sub
'Regresa una lista con los nombres de los contactos del telefono.
Sub getContactos As List
Dim cr As ContentResolver
cr.Initialize("cr")
Private PeopleProjection() As String = Array As String("display_name")
Private l As List
l.Initialize
Dim u As Uri
u.Parse("content://com.android.contacts/contacts")
Dim c As Cursor = cr.Query(u, PeopleProjection, "", Null, "display_name")
For i = 0 To c.RowCount - 1
c.Position = i
' Log($"${c.GetString("display_name")}"$)
l.Add(c.GetString("display_name"))
Next
c.Close
Return l
End Sub
'Remove duplicates from a list.
'Returns the list without duplicates.
Sub removeListDuplicates(pList As List) As List
If pList = Null Or Not(pList.IsInitialized) Then Return pList
If Starter.logger Then Log(pList)
Dim lstNew As List : lstNew.Initialize
Dim objItem As Object
For i = 0 To pList.Size - 1
objItem = pList.Get(i)
If lstNew.IndexOf(objItem) = - 1 Then
lstNew.Add(objItem)
End If
Next
If Starter.logger Then Log(lstNew)
Return lstNew
End Sub
'Manda un mensaje al número especificado (+52 55 XXXX XXXX) mediante un objeto SBN (StatusBarNotification).
'Es necesario que se haya recibido previamente un mensaje del numero especificado.
Sub mandaWAMsjSBN(numero As String, mensaje As String) 'ignore
If numero = Null Then numero = "+52 55 5419 2439"
Dim tempMap As Map = NotificationService.notisMap2.Get(numero)
If tempMap.IsInitialized Then
Dim t1 As lasNotis = tempMap.Get(numero)
Dim t2 As StatusBarNotification = t1.notif
If t2.IsInitialized Then
NotificationService.rp.reply(t2.Notification, t2.PackageName, mensaje)
CallSubDelayed3(NotificationService, "guardaMsjSalida", t2, mensaje)
End If
Else
ToastMessageShow($"No hay notificaciones de ${numero}"$, False)
End If
End Sub
'Converts an image to a bytes array (for BLOB fields).
Public Sub ImageToBytes(Image As Bitmap) As Byte()
Dim out As OutputStream
out.InitializeToBytesArray(0)
Image.WriteToStream(out, 100, "JPEG")
out.Close
Return out.ToBytesArray
End Sub
'Manda un mensaje al número especificado (52155XXXXXXXX) mediante un script de shell y root.
'El celular necesita estar rooteado.
'El destinatario debe tener la lada completa sin signos de mas, es decir, para mexico 521 + el numero a 10 digitos.
Sub mandaWAMsjRoot(mensaje As String, destinatario As String) 'ignore
Private waPackage As String = "com.whatsapp"
Dim Command, Runner As String
Dim StdOut, StdErr As StringBuilder
StdOut.Initialize
StdErr.Initialize
Dim Result As Int
Dim Ph As Phone
Private jid As String = $"${destinatario}@s.whatsapp.net"$
Private key_id As String = $"${DateTime.Now}-1"$
Private mensaje As String = $"/msjTest ${mensaje} ${DateTime.Time(DateTime.Now)}"$
Private received_timestamp As String = "0"
' Log(key_id)
' *******************************************************************************************
' *******************************************************************************************
' Hay que revisar que el numero del destinatario exista en la tabla "jid.user" y si no existe, entonces agregarlo:
' user server Agent Type raw_string device
' 5215554192439 s.whatsapp.net 0 0 5215554192439@s.whatsapp.net 0
' Hay que agregar en la tabla "chat":
' - el renglon correspondiente de la tabla "jid" (_id) en "jid_row_id".
' - el renglon correspondiente de la tabla "messages" (_id) en "display_message_row_id".
' - y mas columnas ...
'Revisamos que exista el numero al que vamos a mandar el mensaje en la tabla "jid".
Private jids As String = hazRootQuery($"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'select _id from jid where user = "${destinatario}" limit 1';"$, "getNumber")
' Log($"|${jids.trim}|"$)
If jids.Trim = "" Then 'Si no existe, entonces lo insertamos.
If Starter.logger Then LogColor("No hay JID, lo insertamos", Colors.Red)
Private sqlInsertJid As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'INSERT INTO jid (user, server, Agent, Type, raw_string, device) VALUES ("${destinatario}", "s.whatsapp.net", 0, 0, "${jid}", 0)';"$
hazRootQuery(sqlInsertJid, "InsertJid") 'Insertamos el numero en la tabla "jid".
End If
'Traemos el jid insertado.
Private elJid As String = hazRootQuery($"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'SELECT _id FROM jid where user = "${destinatario}" limit 1';"$, "GetJid")
elJid = elJid.trim
' Log("****** "&elJid)
' *******************************************************************************************
' Agregamos el mensaje a la tabla "messages".
' *******************************************************************************************
Private suCmd As String = $"sqlite3 /data/data/com.whatsapp/databases/msgstore.db 'INSERT INTO messages (key_remote_jid,key_from_me,key_id,status,needs_push,data,timestamp,media_url,media_mime_type,media_wa_type,media_size,media_name,media_hash,latitude,longitude,thumb_image,remote_resource,received_timestamp,send_timestamp,receipt_server_timestamp,receipt_device_timestamp,raw_data,recipient_count,media_duration,origin) VALUES ("${jid}", 1, "${key_id}",0,0,"${mensaje}",${key_id},"","",0,0,"","",0,0,"","",${received_timestamp},-1,-1,-1,"",0,0,0)';"$
' Private suCmd As String = $"sqlite3 /data/data/com.gbwhatsapp/databases/msgstore.db 'SELECT _id, key_remote_jid, data FROM messages WHERE data like "Test%"';"$
Runner = File.Combine(File.DirInternalCache, "runner")
Command = File.Combine(File.DirInternalCache, "command")
File.WriteString(File.DirInternalCache, "runner", "su < " & Command)
File.WriteString(File.DirInternalCache, "command", suCmd & CRLF & "exit") 'Any commands via crlf, and exit at end
Result = Ph.Shell("sh", Array As String(Runner), StdOut, StdErr)
' Log(Result)
If Result = 0 Then ToastMessageShow("Mensaje enviado", False)
'Traemos el id del ultimo mensaje de la tabla "messages".
Private lastMsgId As Int = hazRootQuery($"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'SELECT max(_id) FROM messages';"$, "GetLastMsgId")
' Log(lastMsgId)
'Revisamos si existe el jid en la tabla "chat".
Private chatJid As String = hazRootQuery($"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'select count(jid_row_id) from chat where jid_row_id = "${elJid}"';"$, "getChatJid")
' Log($"|${chatJid.trim}|"$)
If chatJid.Trim > 0 Then 'Actualizamos los datos necesarios en la tabla "chat".
Private sqlUpdateChat As String = hazRootQuery($"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'update chat set hidden = 0, display_message_row_id = ${lastMsgId}, last_message_row_id = ${lastMsgId}, last_read_message_row_id = ${lastMsgId}, last_read_receipt_sent_message_row_id = ${(lastMsgId-1)}, last_important_message_row_id = 1, archived = 0, sort_timestamp = ${DateTime.Now} where jid_row_id = ${elJid}';"$, "updateChat")
' Log("Actualizamos en CHAT")
Else 'Insertamos los datos necesarios a la tabla "chat"
Private sqlInsertChat As String = hazRootQuery($"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'insert into chat
(jid_row_id, hidden, display_message_row_id, last_message_row_id, last_read_message_row_id, last_read_receipt_sent_message_row_id, last_important_message_row_id, archived, sort_timestamp, mod_tag, spam_detection, unseen_earliest_message_received_time, unseen_message_count, unseen_missed_calls_count, unseen_row_count, plaintext_disabled, vcard_ui_dismissed, change_number_notified_message_row_id, show_group_description, ephemeral_expiration, ephemeral_setting_timestamp, unseen_important_message_count, ephemeral_disappearing_messages_initiator, group_type, last_message_reaction_row_id, last_seen_message_reaction_row_id, unseen_message_reaction_count, last_read_message_sort_id, display_message_sort_id, last_message_sort_id, last_read_receipt_sent_message_sort_id)
values (${elJid}, 0, ${lastMsgId}, ${lastMsgId}, ${lastMsgId}, ${(lastMsgId-1)}, 1, 0, ${DateTime.Now}, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, ${lastMsgId}, ${lastMsgId}, ${lastMsgId}, ${(lastMsgId-1)})';"$, "insertChat")
' Log("Insertamos en CHAT")
End If
'Obtenemos el id del ultimo mensaje
' Private suCmd1 As String = $"sqlite3 /data/data/com.whatsapp/databases/msgstore.db 'SELECT max(_id) FROM messages';"$
' Dim nextId As Int = hazRootQuery(suCmd1, "GetId")
' Log("Last ID="&nextId)
' 'Insertamos un boton
' Private suCmd As String = $"sqlite3 /data/data/com.whatsapp/databases/msgstore.db 'INSERT INTO message_template_button (message_row_id, text_data, extra_data, button_type, used) VALUES ("${nextId}", "Boton de Prueba", "Boton de prueba", 0, 1)';"$
' hazRootQuery(suCmd, "guardaBoton")
Private suCmd As String = $"killall com.whatsapp"$
Runner = File.Combine(File.DirInternalCache, "runner")
Command = File.Combine(File.DirInternalCache, "command")
File.WriteString(File.DirInternalCache, "runner", "su < " & Command)
File.WriteString(File.DirInternalCache, "command", suCmd & CRLF & "exit") 'Any commands via crlf, and exit at end
Result = Ph.Shell("sh", Array As String(Runner), StdOut, StdErr)
If Starter.logger Then Log("Kill WA result : " & Result)
If Starter.logger Then LogColor(StdOut.tostring, Colors.red)
' hazRootQuery("killall com.whatsapp", "Kill_WA")
End Sub
'Manda un mensaje con imagen al número especificado (52155XXXXXXXX) mediante un script de shell y root.
'El celular necesita estar rooteado.
Sub mandaWAImageRoot_0(m As String) 'ignore
Starter.waDb.Initialize("/sdcard/", "msgstore_no_enviado.db", True)
Dim waPackage, Command, Runner As String
Dim StdOut, StdErr, StdOut2, StdErr2 As StringBuilder
StdOut.Initialize
StdErr.Initialize
StdOut2.Initialize
StdErr2.Initialize
waPackage = Starter.waPackage
Dim Result As Int
Dim Ph As Phone
' Private suCmd As String = $"sqlite3 /data/data/com.whatsapp/databases/msgstore.db 'SELECT _id, key_remote_jid, data FROM messages WHERE data like "Test%"';"$
Private jid As String = "5215554192439@s.whatsapp.net"
Private key_id As String = $"${DateTime.Now}-1"$
Private timeStamp As Int = DateTime.Now
' Private mensaje As String = $"/msjTest ${m} ${DateTime.Time(DateTime.Now)}"$
' Private received_timestamp As String = "0"
Private keyId As String = ""
If Starter.logger Then Log(key_id)
Private suCmd3 As String = $"killall ${waPackage}"$
Runner = File.Combine(File.DirInternalCache, "runner")
Command = File.Combine(File.DirInternalCache, "command")
File.WriteString(File.DirInternalCache, "runner", "su < " & Command)
File.WriteString(File.DirInternalCache, "command", suCmd3 & CRLF & "exit") 'Any commands via crlf, and exit at end
Result = Ph.Shell("sh", Array As String(Runner), StdOut2, StdErr2)
If Starter.logger Then Log(Result)
If Result = 0 Then Log("process killed")
If Starter.logger Then LogColor(StdOut2.tostring, Colors.red)
If Starter.logger Then Log(StdOut2)
If Starter.logger Then LogColor(StdErr2, Colors.Magenta)
Private suCmd1 As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'Select chat._id as chatId FROM chat JOIN jid ON jid._id = chat.jid_row_id where jid.raw_string = "5215554192439@s.whatsapp.net" limit 1';"$
Private chatId As String = hazRootQuery(suCmd1, "getChatId")
Private mediaCaption As String = "Alo Papagena … Tore bella com la papaia"
' suCmd1 = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'Select messages.* from messages join message_media on messages._id = message_media.message_row_id order by _id desc limit 1';"$
' Log(hazRootQuery(suCmd1, "GetMsj"))
Dim c As Cursor = Starter.waDb.ExecQuery("Select messages.* from messages join message_media on messages._id = message_media.message_row_id order by _id desc limit 1") 'El ultimo mensaje que tenga imagen
If c.RowCount > 0 Then
c.Position = 0
keyId = c.GetString("key_id")
Private suCmd1 As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'INSERT INTO messages (key_remote_jid, key_from_me, key_id, status, needs_push, timestamp, media_wa_type, media_size, media_name, media_caption, media_hash, media_duration,origin, latitude, longitude, received_timestamp, send_timestamp, receipt_server_timestamp, receipt_device_timestamp, recipient_count, quoted_row_id, edit_version, media_enc_hash, forwarded, preview_type, lookup_tables, future_message_type, message_add_on_flags) VALUES ("${jid}", ${c.GetInt("key_from_me")}, "${key_id}", 0, ${c.GetInt("needs_push")}, ${timeStamp}, "${c.GetString("media_wa_type")}", ${c.GetInt("media_size")}, "${c.GetString("media_name")}", "${mediaCaption}", "${c.GetString("media_hash")}", ${c.GetInt("media_duration")}, ${c.GetInt("origin")}, ${c.GetDouble("latitude")}, ${c.GetDouble("longitude")}, ${c.GetInt("received_timestamp")}, ${c.GetInt("send_timestamp")}, -1, -1, ${c.GetInt("recipient_count")}, ${c.GetInt("quoted_row_id")}, ${c.GetInt("edit_version")}, "${c.GetString("media_enc_hash")}", ${c.GetInt("forwarded")}, ${c.GetInt("preview_type")}, ${c.GetInt("lookup_tables")}, ${c.GetInt("future_message_type")}, ${c.GetInt("message_add_on_flags")})';"$
hazRootQuery(suCmd1, "Messages") 'Insertamos los datos en la tabla "messages".
Private msgId As Int = c.GetInt("_id")
End If
c.Close
Private suCmd1 As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'SELECT max(_id) FROM messages';"$
Dim nextId As Int = hazRootQuery(suCmd1, "GetId")
Dim c As Cursor = Starter.waDb.ExecQuery($"select * from message_media where message_row_id = '${msgId}'"$)
If c.RowCount > 0 Then
c.Position = 0
Private filePath As String = c.GetString("file_path")
Private suCmd2 As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'insert into message_media (message_row_id, chat_row_id, autotransfer_retry_enabled, media_job_uuid, transferred, transcoded, file_path, file_size, suspicious_content, trim_from, trim_to, face_x, face_y, media_key_timestamp, width, height, has_streaming_sidecar, gif_attribution, thumbnail_height_width_ratio, first_scan_length, file_length, media_name, file_hash, media_duration, page_count, enc_file_hash, is_animated_sticker, mute_video) values (${nextId}, ${chatId}, 1, "${c.getString("media_job_uuid")}", 0, ${c.getInt("transcoded")}, "${filePath}", ${c.getInt("file_size")}, ${c.getInt("suspicious_content")}, ${c.getInt("trim_from")}, ${c.getInt("trim_to")}, ${c.getInt("face_x")}, ${c.getInt("face_y")}, ${c.getInt("media_key_timestamp")}, ${c.getInt("width")}, ${c.getInt("height")}, ${c.getInt("has_streaming_sidecar")}, ${c.getInt("gif_attribution")}, ${c.GetDouble("thumbnail_height_width_ratio")}, ${c.getInt("first_scan_length")}, ${c.getInt("file_length")}, "${c.getString("media_name")}", "${c.getString("file_hash")}", ${c.getInt("media_duration")}, ${c.getInt("page_count")}, "${c.getString("enc_file_hash")}", ${c.getInt("is_animated_sticker")}, ${c.getInt("mute_video")})';"$
If Starter.logger Then Log(hazRootQuery(suCmd2, "MsgMedia"))
' If Result = 0 Then Log("inserted --> message_media")
End If
c.Close
' Log($"readfile(${filePath}), ${timeStamp}, ${jid}, 1, ${keyId}"$)
Private suCmd2 As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'insert into message_thumbnails (thumbnail, timestamp, key_remote_jid, key_from_me, key_id) values (readfile("${filePath}"), ${timeStamp}, "${jid}", 1, "${key_id}")';"$
If Starter.logger Then Log(hazRootQuery(suCmd2, "msgThumbnails"))
End Sub
Sub hazRootQuery(qryStr As String, name As String) As StringBuilder
' Starter.waDb.Initialize("/sdcard/", "msgstore_no_enviado.db", True)
Dim Command, Runner As String
Dim StdOut, StdErr As StringBuilder
StdOut.Initialize
StdErr.Initialize
Dim Result As Int
Dim Ph As Phone
Runner = File.Combine(File.DirInternalCache, "runner")
Command = File.Combine(File.DirInternalCache, "command")
File.WriteString(File.DirInternalCache, "runner", "su < " & Command)
File.WriteString(File.DirInternalCache, "command", qryStr & CRLF & "exit") 'Any commands via crlf, and exit at end
Result = Ph.Shell("sh", Array As String(Runner), StdOut, StdErr)
' Log(name&" "&"Res="&Result)
' Log(StdOut)
If Starter.logger Then LogColor(StdErr, Colors.red)
If StdErr.Length > 1 Then LogColor(qryStr, Colors.Blue)
Return StdOut
End Sub
Sub copyWADB 'ignore
Dim waPackage, Command, Runner As String
Dim StdOut, StdErr As StringBuilder
StdOut.Initialize
StdErr.Initialize
waPackage = Starter.waPackage
Dim Result As Int
Dim Ph As Phone
Private suCmd3 As String = $"killall ${waPackage}"$
Runner = File.Combine(File.DirInternalCache, "runner")
Command = File.Combine(File.DirInternalCache, "command")
File.WriteString(File.DirInternalCache, "runner", "su < " & Command)
File.WriteString(File.DirInternalCache, "command", suCmd3 & CRLF & "exit") 'Any commands via crlf, and exit at end
Result = Ph.Shell("sh", Array As String(Runner), StdOut, StdErr)
If Starter.logger Then Log(Result)
If Result = 0 Then Log("process killed")
If Starter.logger Then LogColor(StdOut.tostring, Colors.red)
If Starter.logger Then Log(StdOut)
If Starter.logger Then LogColor(StdErr, Colors.Magenta)
Private suCmd As String = $"sqlite3 /data/user/0/${waPackage}/databases/msgstore.db 'PRAGMA wal_checkpoint;'
cp /data/data/${waPackage}/databases/msgstore.db /sdcard/msgstore.db"$
If Starter.logger Then LogColor(suCmd, Colors.Blue)
Runner = File.Combine(File.DirInternalCache, "runner")
Command = File.Combine(File.DirInternalCache, "command")
File.WriteString(File.DirInternalCache, "runner", "su < " & Command)
File.WriteString(File.DirInternalCache, "command", suCmd & CRLF & "exit") 'Any commands via crlf, and exit at end
Result = Ph.Shell("sh", Array As String(Runner), StdOut, StdErr)
If Starter.logger Then Log(Result)
If Starter.logger Then Log(StdOut)
If Starter.logger Then LogColor(StdErr, Colors.Magenta)
If Result = 0 Then Log("copied db")
End Sub
'Regresa una lista de mapas con los datos con los ultimos mensajes con imagen enviados.
'Con este mapa se puede generar un nuevo mensaje con imagen.
Sub traeImgMsjData As List
Private regs As List
regs.Initialize
Private sqlSync As String = $"sqlite3 /data/user/0/${Starter.waPackage}/databases/msgstore.db 'PRAGMA wal_checkpoint;'"$
Private sync As String = hazRootQuery(sqlSync, "syncDB") 'Guardamos los datos en la DB 'ignore
' Private suCmd2 As String = $"sqlite3 /data/data/${Starter.waPackage}/databases/msgstore.db 'select * from messages join message_media on message_row_id = _id limit 20';"$
Private suCmd2 As String = $"sqlite3 /data/data/${Starter.waPackage}/databases/msgstore.db 'select _id, key_remote_jid, key_from_me, key_id, status, needs_push, timestamp, media_url, media_mime_type, media_wa_type, media_size, messages.media_name, media_caption, media_hash, messages.media_duration, origin, latitude, longitude, remote_resource, received_timestamp, send_timestamp, receipt_server_timestamp, receipt_device_timestamp, read_device_timestamp, played_device_timestamp, raw_data, recipient_count, participant_hash, starred, quoted_row_id, mentioned_jids, messages.multicast_id, edit_version, media_enc_hash, payment_transaction_id, forwarded, preview_type, send_count, lookup_tables, future_message_type, message_add_on_flags, message_row_id, chat_row_id, autotransfer_retry_enabled, message_media.multicast_id, media_job_uuid, transferred, transcoded, file_path, file_size, suspicious_content, trim_from, trim_to, face_x, face_y, media_key_timestamp, width, height, has_streaming_sidecar, gif_attribution, thumbnail_height_width_ratio, direct_path, first_scan_sidecar, first_scan_length, message_url, mime_type, file_length, message_media.media_name, file_hash, message_media.media_duration, page_count, enc_file_hash, partial_media_hash, partial_media_enc_hash, is_animated_sticker, original_file_hash, mute_video from messages join message_media on message_row_id = _id limit 20';"$
Private tempData As String = hazRootQuery(suCmd2, "traeImgMsjData").As(StringBuilder).ToString
Private renglon() As String = Regex.Split(CRLF, tempData)
' Log("======= _"&renglon.Length&"_|"&tempData)
For i = 0 To renglon.Length -1
' LogColor($"i=${i}, ${renglon(i)}"$, Colors.Blue)
Private columna() As String = Regex.Split("\|", renglon(i))
' For col = 0 To columna.Length - 1
' Log($"col=${col}, ${columna(col)}"$)
' Next
If columna.Length > 47 Then
Private theDir As String = Starter.waDir & "/" &columna(48)
' Log(theDir)
If theDir.EndsWith("jpg") Or theDir.EndsWith("png") Then
If File.Exists(theDir.SubString2(0, theDir.LastIndexOf("/")+1), theDir.SubString(theDir.LastIndexOf("/")+1)) Then
Private msjData As Map = CreateMap("_id":columna(0), "key_remote_jid":columna(1), "key_from_me":columna(2), "key_id":columna(3), "status":columna(4), "needs_push":columna(5), "timestamp":columna(6), "media_url":columna(7), "media_mime_type":columna(8), "media_wa_type":columna(9), "media_size":columna(10), "media_name":columna(11), "media_caption":columna(12), "media_hash":columna(13), "media_duration":columna(14), "origin":columna(15), "latitude":columna(16), "longitude":columna(17), "remote_resource":columna(18), "received_timestamp":columna(19), "send_timestamp":columna(20), "receipt_server_timestamp":columna(21), "receipt_device_timestamp":columna(22), "read_device_timestamp":columna(23), "played_device_timestamp":columna(24), "raw_data":columna(25), "recipient_count":columna(26), "participant_hash":columna(27), "starred":columna(28), "quoted_row_id":columna(29), "mentioned_jids":columna(30), "multicast_id":columna(31), "edit_version":columna(32), "media_enc_hash":columna(33), "payment_transaction_id":columna(34), "forwarded":columna(35), "preview_type":columna(36), "send_count":columna(37), "lookup_tables":columna(38), "future_message_type":columna(39), "message_add_on_flags":columna(40))
Private imgData As Map = CreateMap("message_row_id":columna(41), "chat_row_id":columna(42), "autotransfer_retry_enabled":columna(43), "multicast_id":columna(44), "media_job_uuid":columna(45), "transferred":columna(46), "transcoded":columna(47), "file_path":columna(48), "file_size":columna(49), "suspicious_content":columna(50), "trim_from":columna(51), "trim_to":columna(52), "face_x":columna(53), "face_y":columna(54), "media_key_timestamp":columna(55), "width":columna(56), "height":columna(57), "has_streaming_sidecar":columna(58), "gif_attribution":columna(59), "thumbnail_height_width_ratio":columna(60), "direct_path":columna(61), "first_scan_sidecar":columna(62), "first_scan_length":columna(63), "message_url":columna(64), "mime_type":columna(65), "file_length":columna(66), "media_name":columna(67), "file_hash":columna(68), "media_duration":columna(69), "page_count":columna(70), "enc_file_hash":columna(71), "partial_media_hash":columna(72), "partial_media_enc_hash":columna(73), "is_animated_sticker":columna(74), "original_file_hash":columna(75), "mute_video":columna(76))
Private thisReg As Map = CreateMap("msjData":msjData, "imgData":imgData)
' LogColor("Agregamos registro "& i, Colors.Magenta)
regs.Add(thisReg)
End If
End If
End If
Next
' Log(regs)
' Log("Registros="&regs.Size)
' For x = 0 To regs.Size-1
' Log(regs.Get(x))
' Next
Return regs
End Sub
'Manda un mensaje con imagen al número especificado (52155XXXXXXXX) mediante un script de shell y root.
'El celular necesita estar rooteado.
Sub mandaWAImageRoot(jid As String, texto As String, msjMap As Map) 'ignore
Starter.waDb.Initialize("/sdcard/", "msgstore_no_enviado.db", True)
jid = "5215554192439@s.whatsapp.net"
Private mediaCaption As String = "Alo Papagena … Tore bella com la papaia"
Private filePath As String = "/storage/F3DF-3FB8/Bow2.0/qr.jpg"
If texto <> "" And texto <> Null Then mediaCaption = texto
Dim waPackage As String = Starter.waPackage
Private key_id As String = $"${DateTime.Now}-1"$
Private timeStamp As String = DateTime.Now
Private keyId As String = ""
If Starter.logger Then Log($"jid=${jid}, timeStamp=${timeStamp}, key_Id=${key_id}, now=${DateTime.Now}"$)
If Starter.logger Then LogColor(msjMap, Colors.Blue)
'============================== Kill Process ==============================
Private killWA As String = hazRootQuery($"killall ${waPackage}"$, "killWA") 'Matamos el proceso de WA 'ignore
'============================================================
Private sqlGetChatId As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'Select chat._id as chatId FROM chat JOIN jid ON jid._id = chat.jid_row_id where jid.raw_string = "${jid}" limit 1';"$
Private chatId As String = hazRootQuery(sqlGetChatId, "getChatId") 'Obtenenos el ID del chat del JID proporcionado.
' Dim c As Cursor = Starter.waDb.ExecQuery("Select messages.* from messages join message_media on messages._id = message_media.message_row_id order by _id desc limit 1") 'El ultimo mensaje que tenga imagen
' If c.RowCount > 0 Then
' c.Position = 0
'=============================== Insert into Messages ==============================
Private msjInfo As Map = msjMap.Get("msjData")
keyId = msjInfo.Get("key_id")
Private sqlInsertMsg As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'INSERT INTO messages (key_remote_jid, key_from_me, key_id, status, needs_push, timestamp, media_wa_type, media_size, media_name, media_caption, media_hash, media_duration, origin, latitude, longitude, received_timestamp, send_timestamp, receipt_server_timestamp, receipt_device_timestamp, recipient_count, quoted_row_id, edit_version, media_enc_hash, forwarded, preview_type, lookup_tables, future_message_type, message_add_on_flags) VALUES ("${jid}", ${msjInfo.Get("key_from_me")}, "${key_id}", 0, ${msjInfo.Get("needs_push")}, ${timeStamp}, "${msjInfo.Get("media_wa_type")}", ${msjInfo.Get("media_size")}, "${msjInfo.Get("media_name")}", "${mediaCaption}", "${msjInfo.Get("media_hash")}", ${msjInfo.Get("media_duration")}, ${msjInfo.Get("origin")}, ${msjInfo.Get("latitude")}, ${msjInfo.Get("longitude")}, ${msjInfo.Get("received_timestamp")}, ${msjInfo.Get("send_timestamp")}, -1, -1, ${msjInfo.Get("recipient_count")}, ${msjInfo.Get("quoted_row_id")}, ${msjInfo.Get("edit_version")}, "${msjInfo.Get("media_enc_hash")}", ${msjInfo.Get("forwarded")}, ${msjInfo.Get("preview_type")}, ${msjInfo.Get("lookup_tables")}, ${msjInfo.Get("future_message_type")}, ${msjInfo.Get("message_add_on_flags")})';"$
If Starter.logger Then LogColor(sqlInsertMsg, Colors.Magenta)
hazRootQuery(sqlInsertMsg, "InsertMessage") 'Insertamos los datos en la tabla "messages".
' Private msgId As Int = msjInfo.Get("_id")
' End If
' c.Close
'=============================== Get last Id =============================
Private sqlGetLastMsgId As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'SELECT max(_id) FROM messages';"$
Dim nextId As Int = hazRootQuery(sqlGetLastMsgId, "GetLastId")
Starter.reglasDB.ExecNonQuery($"INSERT INTO datosMsj (_id, key_remote_jid, key_from_me, key_id, status, needs_push, timestamp, media_wa_type, media_size, media_name, media_caption, media_hash, media_duration, origin, latitude, longitude, received_timestamp, send_timestamp, receipt_server_timestamp, receipt_device_timestamp, recipient_count, quoted_row_id, edit_version, media_enc_hash, forwarded, preview_type, lookup_tables, future_message_type, message_add_on_flags) VALUES ("${nextId}", "${jid}", ${msjInfo.Get("key_from_me")}, "${key_id}", 0, ${msjInfo.Get("needs_push")}, ${timeStamp}, "${msjInfo.Get("media_wa_type")}", ${msjInfo.Get("media_size")}, "${msjInfo.Get("media_name")}", "${mediaCaption}", "${msjInfo.Get("media_hash")}", ${msjInfo.Get("media_duration")}, ${msjInfo.Get("origin")}, ${msjInfo.Get("latitude")}, ${msjInfo.Get("longitude")}, ${msjInfo.Get("received_timestamp")}, ${msjInfo.Get("send_timestamp")}, -1, -1, ${msjInfo.Get("recipient_count")}, ${msjInfo.Get("quoted_row_id")}, ${msjInfo.Get("edit_version")}, "${msjInfo.Get("media_enc_hash")}", ${msjInfo.Get("forwarded")}, ${msjInfo.Get("preview_type")}, ${msjInfo.Get("lookup_tables")}, ${msjInfo.Get("future_message_type")}, ${msjInfo.Get("message_add_on_flags")})"$)
' Dim c As Cursor = Starter.waDb.ExecQuery($"select * from message_media where message_row_id = '${msgId}'"$)
' If c.RowCount > 0 Then
' c.Position = 0
'=============================== Insert into message_media ============================
Private imgInfo As Map = msjMap.Get("imgData")
Private theDir As String = Starter.waDir & "/" & imgInfo.get("file_path")
If Starter.logger Then Log("file_path="&imgInfo.get("file_path"))
If Starter.logger Then Log($"ImgDir=${theDir}"$)
If File.Exists(theDir.SubString2(0, theDir.LastIndexOf("/")+1), theDir.SubString(theDir.LastIndexOf("/")+1)) Then
File.Copy(theDir.SubString2(0, theDir.LastIndexOf("/")+1), theDir.SubString(theDir.LastIndexOf("/")+1), "/sdcard/Bow2.0/", theDir.SubString(theDir.LastIndexOf("/")+1))
filePath = "/sdcard/Bow2.0/" & theDir.SubString(theDir.LastIndexOf("/")+1)
End If
If Starter.logger Then LogColor($"filePath=${filePath}"$, Colors.Magenta)
Private sqlInsertMedia As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'insert into message_media (message_row_id, chat_row_id, autotransfer_retry_enabled, media_job_uuid, transferred, transcoded, file_path, file_size, suspicious_content, trim_from, trim_to, face_x, face_y, media_key_timestamp, width, height, has_streaming_sidecar, gif_attribution, thumbnail_height_width_ratio, first_scan_length, file_length, media_name, file_hash, media_duration, page_count, enc_file_hash, is_animated_sticker, mute_video) values (${nextId}, ${chatId}, 1, "abcd${imgInfo.get("media_job_uuid").As(String).SubString(4)}", 0, ${imgInfo.get("transcoded")}, "${filePath}", ${imgInfo.get("file_size")}, ${imgInfo.get("suspicious_content")}, ${imgInfo.get("trim_from")}, ${imgInfo.get("trim_to")}, ${imgInfo.get("face_x")}, ${imgInfo.get("face_y")}, ${imgInfo.get("media_key_timestamp")}, ${imgInfo.get("width")}, ${imgInfo.get("height")}, ${imgInfo.get("has_streaming_sidecar")}, ${imgInfo.get("gif_attribution")}, ${imgInfo.get("thumbnail_height_width_ratio")}, ${imgInfo.get("first_scan_length")}, ${imgInfo.get("file_length")}, "${imgInfo.get("media_name")}", "${imgInfo.get("file_hash")}", ${imgInfo.get("media_duration")}, ${imgInfo.get("page_count")}, "${imgInfo.get("enc_file_hash")}", ${imgInfo.get("is_animated_sticker")}, ${imgInfo.get("mute_video")})';"$
If Starter.logger Then LogColor(sqlInsertMedia, Colors.Magenta)
If Starter.logger Then Log(hazRootQuery(sqlInsertMedia, "MsgMedia"))
Starter.reglasDB.ExecNonQuery($"insert into datosImg (message_row_id, chat_row_id, autotransfer_retry_enabled, media_job_uuid, transferred, transcoded, file_path, file_size, suspicious_content, trim_from, trim_to, face_x, face_y, media_key_timestamp, width, height, has_streaming_sidecar, gif_attribution, thumbnail_height_width_ratio, first_scan_length, file_length, media_name, file_hash, media_duration, page_count, enc_file_hash, is_animated_sticker, mute_video) values (${nextId}, ${chatId}, 1, "abcd${imgInfo.get("media_job_uuid").As(String).SubString(4)}", 0, ${imgInfo.get("transcoded")}, "${filePath}", ${imgInfo.get("file_size")}, ${imgInfo.get("suspicious_content")}, ${imgInfo.get("trim_from")}, ${imgInfo.get("trim_to")}, ${imgInfo.get("face_x")}, ${imgInfo.get("face_y")}, ${imgInfo.get("media_key_timestamp")}, ${imgInfo.get("width")}, ${imgInfo.get("height")}, ${imgInfo.get("has_streaming_sidecar")}, ${imgInfo.get("gif_attribution")}, ${imgInfo.get("thumbnail_height_width_ratio")}, ${imgInfo.get("first_scan_length")}, ${imgInfo.get("file_length")}, "${imgInfo.get("media_name")}", "${imgInfo.get("file_hash")}", ${imgInfo.get("media_duration")}, ${imgInfo.get("page_count")}, "${imgInfo.get("enc_file_hash")}", ${imgInfo.get("is_animated_sticker")}, ${imgInfo.get("mute_video")})"$)
' If Result = 0 Then Log("inserted --> message_media")
' End If
' c.Close
'=============================== Insert into message_thumbnails ============================
Private sqlInsertThumb As String = $"sqlite3 /data/data/${waPackage}/databases/msgstore.db 'insert into message_thumbnails (thumbnail, timestamp, key_remote_jid, key_from_me, key_id) values (readfile("${filePath}"), ${timeStamp}, "${jid}", 1, "${key_id}")';"$
If Starter.logger Then LogColor(sqlInsertThumb, Colors.Magenta)
If Starter.logger Then Log(hazRootQuery(sqlInsertThumb, "msgThumbnails"))
End Sub