Requests added
This commit is contained in:
parent
3bfad0f6ad
commit
4cad738f0e
|
@ -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")
|
||||
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"))
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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? {
|
||||
|
@ -40,3 +42,18 @@ fun String.md5(): String {
|
|||
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")
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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" }
|
||||
|
|
Loading…
Reference in New Issue