Requests added

This commit is contained in:
leca 2024-10-12 04:37:32 +03:00
parent 3bfad0f6ad
commit 4cad738f0e
11 changed files with 137 additions and 70 deletions

View File

@ -34,7 +34,6 @@ android {
viewBinding = true
}
}
var cameraxVersion = "1.0.1"
dependencies {
implementation(libs.androidx.core.ktx)
@ -49,7 +48,9 @@ dependencies {
implementation(libs.androidx.legacy.support.v4)
implementation(libs.androidx.fragment)
testImplementation(libs.junit)
implementation(libs.volley)
androidTestImplementation(libs.androidx.junit)
implementation (libs.play.services.code.scanner)
androidTestImplementation(libs.androidx.espresso.core)
// implementation("com.google.android.material:1.2.0")
@ -58,8 +59,8 @@ dependencies {
implementation (libs.barcode.scanning)
// CameraX library
implementation ("androidx.camera:camera-camera2:$cameraxVersion")
implementation ("androidx.camera:camera-lifecycle:$cameraxVersion")
implementation (libs.androidx.camera.camera2)
implementation (libs.androidx.camera.lifecycle)
implementation (libs.androidx.camera.view)
implementation ("com.google.android.gms:play-services-code-scanner:16.1.0")
}

View File

@ -12,6 +12,7 @@
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"

View File

@ -11,6 +11,7 @@ import java.io.File
object AbstractProductContract {
object AbstractProductEntry : BaseColumns {
const val TABLE_NAME = "abstract_products"
const val BARCODE = "barcode"
const val PRODUCT_NAME = "name"
const val PRODUCT_NET_WEIGHT = "net_weight"
const val IMAGE_FILENAME = "image_filename"
@ -38,6 +39,7 @@ object ProductContract {
const val SQL_CREATE_ABSTRACT_PRODUCTS_TABLE =
"CREATE TABLE ${AbstractProductContract.AbstractProductEntry.TABLE_NAME} (" +
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
"${AbstractProductContract.AbstractProductEntry.BARCODE} TEXT," +
"${AbstractProductContract.AbstractProductEntry.PRODUCT_NAME} TEXT," +
"${AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT} REAL," +
"${AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME} TEXT," +
@ -101,6 +103,7 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
var result = mutableListOf<AbstractProduct>()
val projection = arrayOf(
BaseColumns._ID,
AbstractProductContract.AbstractProductEntry.BARCODE,
AbstractProductContract.AbstractProductEntry.PRODUCT_NAME,
AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME,
AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT,
@ -114,11 +117,12 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
with(cursor) {
while (moveToNext()) {
val abstractProductId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
val abstractProductBarcode = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.BARCODE))
val abstractProductName = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
val abstractProductNetWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
val abstractProductImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
val abstractProduct = AbstractProduct(abstractProductId, abstractProductName, abstractProductNetWeight, abstractProductImageHash, category = id)
val abstractProduct = AbstractProduct(abstractProductId, abstractProductBarcode, abstractProductName, abstractProductNetWeight, abstractProductImageHash, category = id)
result.add(abstractProduct)
}

View File

@ -2,46 +2,57 @@ package org.foxarmy.barcodescannerforemployees
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
class Parser constructor(payloadStartRegex: String, payloadEndRegex: String, payloadRegex: String){
val payloadStartRegex: String = payloadStartRegex
val payloadEndRegex: String = payloadEndRegex
val payloadRegex: String = payloadRegex
class Parser constructor() {
fun parse(text: String): AbstractProduct {
var text = text
fun parse(text: String): MutableList<AbstractProduct> {
var name = ""
var netWeight = 0.0
val payloadStart = Regex(payloadStartRegex)
val payloadEnd = Regex(payloadEndRegex)
val payload = Regex(payloadRegex)
val startFound = payloadStart.find(text)?.value.toString()
val payloadStartIndex = text.indexOf(startFound)
var clearText = text.removeRange(
0,
if (payloadStartIndex < 0) 0 else payloadStartIndex
)
val endFound = payloadEnd.find(clearText)?.value.toString()
val payloadEndIndex = clearText.indexOf(endFound)
clearText = clearText.removeRange(
if (payloadEndIndex < 0) 0 else payloadEndIndex - 1,
clearText.length
)
println(clearText)
var products = payload.findAll(clearText).toMutableList()
for (product in products) {
println(product.value)
//Find volume in liters
val litersRegex = Regex("[0-9+],[0-9*]\\s*[лЛ]")
val foundLiters = litersRegex.find(text)
if (foundLiters != null) {
text = text.replace(foundLiters.groupValues[0], "")
netWeight = stripNetWeight(foundLiters.groupValues[0])
} else { // not found liters. Maybe milliliters?
val millilitersRegex = Regex("[0-9+],[0-9*]\\s*((мл)|(МЛ)|(Мл))")
val foundMilliliters = millilitersRegex.find(text)
netWeight = if (foundMilliliters != null) {
text = text.replace(foundMilliliters.groupValues[0], "")
stripNetWeight(foundMilliliters.groupValues[0]) / 1000 // Found milliliters, convert to liters
} else {
0.0 // Nothing found
}
}
return mutableListOf()
val kilogramRegex = Regex("[0-9+],[0-9*]\\s*((кг)|(Кг))")
val foundKilograms = kilogramRegex.find(text)
if (foundKilograms != null) {
text = text.replace(foundKilograms.groupValues[0], "")
netWeight = stripNetWeight(foundKilograms.groupValues[0]) * 1000
} else { // Not found kilograms, maybe we could find grams?
val gramsRegex = Regex("[0-9+],[0-9*]\\s*[гГ]")
val foundGrams = gramsRegex.find(text)
netWeight = if (foundGrams != null) {
text = text.replace(foundGrams.groupValues[0], "")
stripNetWeight(foundGrams.groupValues[0])
} else {
0.0 // Nothing found
}
}
val piecesRegex = Regex("[0-9+],*[0-9*]\\s*((шт)|(Шт))")
val foundPieces = piecesRegex.find(text)
if (foundPieces != null) {
text = text.replace(foundPieces.groupValues[0], "")
netWeight = stripNetWeight(foundPieces.groupValues[0])
} else {
netWeight = 0.0
}
name = text
return AbstractProduct(0, "", name, netWeight, "", 0)
}
}
fun main () {
val p = Parser("""\<table\s*class\=\"randomBarcodes\"\s*>""", """\<\/table\>""", """[ёЁ\u0401\u0451\u0410-\u044f\d\w\s]{16,}""")
p.parse(Requester("https://barcode-list.ru", "barcode/RU/Поиск.htm?barcode=4680036915828", ).request("4680036915828"))
// println(Requester("https://barcode-list.ru", "barcode/RU/Поиск.htm?barcode=4680036915828", ).request("4680036915828"))
}

View File

@ -1,28 +1,35 @@
package org.foxarmy.barcodescannerforemployees
import java.net.HttpURLConnection
import java.net.URL
import android.content.Context
import android.widget.Toast
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
class Requester constructor(siteName:String, endpoint: String) {
var siteName: String = siteName
var endpoint: String = endpoint
class Requester constructor(var siteName: String, var endpoint: String) {
var response = ""
fun request (productId: String): String {
val url = URL("${siteName}/$endpoint")
fun request(context: Context, barcode: String) {
val url = "${siteName}/${endpoint}"
var response: String = ""
val volleyQueue = Volley.newRequestQueue(context)
val stringRequest = object: StringRequest(
Method.POST, url, { resp ->
run {
response = resp
}
},
{
Toast.makeText(context, "Cannot make request", Toast.LENGTH_LONG).show()
}
) {
override fun getHeaders(): Map<String, String> {
return mapOf("referer" to "$siteName/")
}
with(url.openConnection() as HttpURLConnection) {
requestMethod = "GET" // optional default is GET
println("\nSent 'GET' request to URL : $url; Response Code : $responseCode")
inputStream.bufferedReader().use {
it.lines().forEach { line ->
response += line //+ '\n'
}
public override fun getParams(): MutableMap<String, String> {
return mutableMapOf("barcode" to barcode)
}
}
return response
volleyQueue.add(stringRequest)
}
}
}

View File

@ -6,12 +6,14 @@ import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.content.FileProvider
import androidx.core.graphics.scale
import com.google.firebase.components.BuildConfig
import java.io.File
import java.io.FileOutputStream
import java.net.URLEncoder
import java.security.MessageDigest
fun getImageUri(activity: Activity, imageFile: File): Uri? {
@ -39,4 +41,19 @@ fun String.md5(): String {
val md = MessageDigest.getInstance("MD5")
val digest = md.digest(this.toByteArray())
return digest.toHexString()
}
}
fun stripNetWeight (netWeight: String): Double {
return removeSubstringsFromString(netWeight, arrayOf("Л", "л", "мл", "Мл", "г", "Г", "кг", "Кг", "шт", "Шт", ",", " ", ".")).toDouble()
}
fun removeSubstringsFromString(text: String, toRemove: Array<String>): String {
var result = text
for (candidate in toRemove.iterator()) {
result = result.replace(candidate, "")
}
Log.d("QWERTYUIOP", result)
return result
}
fun String.utf8(): String = URLEncoder.encode(this, "UTF-8")

View File

@ -18,6 +18,7 @@ import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
import java.io.File
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import kotlin.concurrent.thread
class AddAbstractProductActivity : AppCompatActivity() {
private lateinit var imageView: ImageView
@ -34,6 +35,7 @@ class AddAbstractProductActivity : AppCompatActivity() {
private var abstractProduct: AbstractProduct? = null
private lateinit var pictureFile: File
private lateinit var picturesPath: File
private lateinit var barcode: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -73,7 +75,7 @@ class AddAbstractProductActivity : AppCompatActivity() {
saveButton.setOnClickListener {
val productName = productNameText.text.toString()
val netWeight = netWeightText.text
if (!this::pictureFile.isInitialized && !pictureFile.exists()) {
if (!this::pictureFile.isInitialized || !pictureFile.exists()) {
Toast.makeText(this, "Please, make a picture of a product!", Toast.LENGTH_SHORT).show()
return@setOnClickListener
@ -89,6 +91,7 @@ class AddAbstractProductActivity : AppCompatActivity() {
val db = DBStorageController(this).writableDatabase
val values = ContentValues().apply {
put(AbstractProductContract.AbstractProductEntry.BARCODE, barcode)
put(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME, productName)
put(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString())
put(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME, pictureFile.nameWithoutExtension)
@ -117,7 +120,21 @@ class AddAbstractProductActivity : AppCompatActivity() {
val scanner = GmsBarcodeScanning.getClient(this)
scanner.startScan()
.addOnSuccessListener { barcode ->
productNameText.setText(barcode.rawValue)
this.barcode = barcode.rawValue.toString()
val requester = Requester("https://ean-online.ru", "match.php")
requester.request(this, barcode.rawValue!!.toString())
var abstractProduct: AbstractProduct
thread {
// Я сам в ахуях какой это костыль, пока хз как фиксить, потом придумаю :))
while (requester.response == "") { }
abstractProduct = Parser().parse(requester.response)
requester.response = ""
runOnUiThread {
productNameText.text = abstractProduct.name
netWeightText.text = abstractProduct.netWeight.toString()
}
}
}
.addOnFailureListener { e ->
Toast.makeText(

View File

@ -5,13 +5,15 @@ import android.os.Parcelable
class AbstractProduct() : Parcelable {
var id: Int = 0
var barcode: String = ""
var name: String = ""
var netWeight: Double = 0.0
var imageHash: String = ""
var category: Int = 0
constructor(id: Int, name: String ,netWeight: Double, imageHash: String, category: Int) : this() {
constructor(id: Int, barcode: String, name: String ,netWeight: Double, imageHash: String, category: Int) : this() {
this.id = id
this.barcode = barcode
this.name = name
this.netWeight = netWeight
this.imageHash = imageHash
@ -20,6 +22,7 @@ class AbstractProduct() : Parcelable {
constructor(parcel: Parcel) : this() {
id = parcel.readInt()
barcode = parcel.readString()!!
name = parcel.readString()!!
netWeight = parcel.readDouble()
imageHash = parcel.readString()!!
@ -28,6 +31,7 @@ class AbstractProduct() : Parcelable {
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(id)
parcel.writeString(barcode)
parcel.writeString(name)
parcel.writeDouble(netWeight)
parcel.writeString(imageHash)
@ -47,5 +51,4 @@ class AbstractProduct() : Parcelable {
return arrayOfNulls(size)
}
}
}

View File

@ -76,6 +76,7 @@ class StorageFragment : Fragment() {
val db = DBStorageController(requireContext()).readableDatabase
val projection = arrayOf(BaseColumns._ID,
AbstractProductContract.AbstractProductEntry.BARCODE,
AbstractProductContract.AbstractProductEntry.PRODUCT_NAME,
AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT,
AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME,
@ -87,12 +88,13 @@ class StorageFragment : Fragment() {
with (cursor) {
while(moveToNext()) {
val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
val barcode = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.BARCODE))
val productName = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
val netWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
val productImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
val category = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.CATEGORY))
val product = AbstractProduct(productId, productName, netWeight, productImageHash, category)
val product = AbstractProduct(productId, barcode, productName, netWeight, productImageHash, category)
generateThumbnailForImage(context!!, productImageHash)

View File

@ -11,10 +11,10 @@ import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.startActivity
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
import org.foxarmy.barcodescannerforemployees.DBStorageController
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.activities.FullscreenActivity
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
import org.foxarmy.barcodescannerforemployees.getImageUri
import java.io.File
@ -59,8 +59,6 @@ class AbstractProductView: LinearLayout {
}
productNameField.text = abstractProduct.name
netWeightField.text = abstractProduct.netWeight.toString()
categoryField.text = DBStorageController(context).getCategoryNameById(DBStorageController(context).readableDatabase, abstractProduct.category)

View File

@ -17,8 +17,12 @@ gridlayout = "1.0.0"
activity = "1.9.2"
legacySupportV4 = "1.0.0"
fragment = "1.8.4"
playServicesCodeScanner = "16.1.0"
volley = "1.2.1"
[libraries]
androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "cameraView" }
androidx-camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "cameraView" }
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraView" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "barcodeScanning" }
@ -35,6 +39,8 @@ androidx-gridlayout = { group = "androidx.gridlayout", name = "gridlayout", vers
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" }
androidx-fragment = { group = "androidx.fragment", name = "fragment", version.ref = "fragment" }
play-services-code-scanner = { module = "com.google.android.gms:play-services-code-scanner", version.ref = "playServicesCodeScanner" }
volley = { module = "com.android.volley:volley", version.ref = "volley" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }