Wednesday 31 August 2022

Django Google News Sitemap

Does anyone know how to implement the google news sitemap standard on Django? https://developers.google.com/search/docs/advanced/sitemaps/news-sitemap

I am struggling to find any mention of how its implemented with Django.

Example of how it should look.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
  <url>
   <loc>http://www.example.org/business/article55.html</loc>
   <news:news>
   <news:publication>
     <news:name>The Example Times</news:name>
     <news:language>en</news:language>
   </news:publication>
   <news:publication_date>2008-12-23</news:publication_date>
     <news:title>Companies A, B in Merger Talks</news:title>
    </news:news>
  </url>
</urlset>

What I currently have looks very simple.

<url>
<loc>https://mynewsite.net/news/this-news-article/</loc>
<lastmod>2022-04-04</lastmod>
</url>
<url>


from Django Google News Sitemap

Changing the Orientation Smoothly for SDK from App

I know the question related to orientation has been asked multiple times, but I am facing some weird issue. I am working on one SDK that has some Activity which can be opened from the App, The SDK asks for the orientation values from the App and I am updating the orientation in onCreate() of the Activity by setting:

requestedOrientation = orientation

It works perfectly when I am holding the device in the same orientation as the orientation is set by App. But If I am holding the device in portrait mode and setting the requestedOrientation to LANDSCAPE then my screen flickers, 1st it shows the portrait screen and then goes to landscape. In manifest I have set the configChanges to android:configChanges="keyboard|keyboardHidden|screenSize" I have separate layouts for both the orientations. Let me know, if anything else is also required.



from Changing the Orientation Smoothly for SDK from App

Android app uses API 31 java 8 instead of installed java 11

I have generated a react native app and want to use the installed java 11 at source code run time instead of java 8.

In android studio when hovering over react-native-gradle-plugin, it uses java 11 which I installed which java -version in terminal is java 11:

enter image description here

Source code used to run the app still use API 31 java 8:

enter image description here enter image description here

Is it possible to pack java 11 into android.jar then replace the java 8 in API 31 folder

app/build.gradle:

enter image description here

SDK:

enter image description here

App structure:

enter image description here

Build tools:

enter image description here



from Android app uses API 31 java 8 instead of installed java 11

React Native Native Java Module Tests run 1 by 1 but won't run under "All Tests"

Under a React Native Project, the TypeScript tests run fine with jest but when we added JUnit tests under a Native Java Module, while it works individually or by folder, whenever we run "All Tests" in Android Studio we get a false fail

Clicking at Project level and selecting "All Tasks"

enter image description here

gives us

enter image description here

No instrumentation registered! Must run under a registering instrumentation.

But

enter image description here

gives us

enter image description here

can anyone shed light onto why this is happening?

As an aside, after trying to fix this via command line, (i.e. in an effort to diagnose it and bypass it perhaps) I have found that when we run these unit tests under ./gradlew test or adb shell am instrument -w -m -e package net.my.package -e debug false net.my.package.test/androidx.test.runner.AndroidJUnitRunner command line test versions, well ./gradlew test always passes, and the adb shell cmd ALWAYS shows a repeat of the last Visual Studio pass/fail regardless of their actual current test condition (i.e .forced to be fail or otherwise). It's only in the Android Studio UI "right click" they pass or fail legitimately. Command line the pass regardless of their suitability.

the Build Gradle is

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    //noinspection GradleDynamicVersion
    implementation "com.facebook.react:react-native:+"  // From node_modules
    implementation project(':react-native-exception-handler')
    implementation project(':react-native-gesture-handler')
    implementation project(':react-native-device-info')
    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
    implementation project(':react-native-safe-area-context')
    implementation project(':react-native-vector-icons')
    implementation project(':react-native-svg')
    implementation'com.facebook.soloader:soloader:0.9.0+'
    implementation 'com.facebook.fresco:animated-gif:2.6.0'
    testImplementation 'androidx.test:core:1.4.0'
   
    androidTestImplementation('com.wix:detox:+') { transitive = true }
    androidTestImplementation 'junit:junit:4.12'


from React Native Native Java Module Tests run 1 by 1 but won't run under "All Tests"

TensorFlow broadcasting of RaggedTensor

How do I subtract a tensor from ragged tensor?

Example:

import tensorflow as tf    # TensorFlow 2.6

X = tf.ragged.constant([[[3, 1], [3]],
                        [[2], [3, 4]]], ragged_rank=2)
y = tf.constant([[1], [2]])
X-y

Expected result:

[[[2, 0], [1]],
 [[1], [1, 2]]]

However, it returns an error:

tensorflow.python.framework.errors_impl.InvalidArgumentError: Expected 'tf.Tensor(False, shape=(), dtype=bool)' to be true. Summarized data: b'Unable to broadcast: dimension size mismatch in dimension'
1
b'lengths='
2
b'dim_size='
2, 2

I know I can do it row-by-row:

result = []
if X.shape[0] is not None:  # Placeholders have None everywhere -> range(None) raises an exception -> this condition
    for row in range(X.shape[0]):
        result.append(X[row] - y)
    result = tf.stack(result)

However, this works only in the eager mode - in graph mode, I get:

ValueError: No gradients provided for any variable

because the code gets executed only conditionally...

What works is to hard-code the count of rows:

for row in range(2):
    result.append(X[row] - y)
result = tf.stack(result)

But that doesn't generalize well.

I also know I can write:

X - tf.expand_dims(y, axis=1)

But that returns a result for "transposed" y:

[[[2, 0], [2]],
 [[0], [1, 2]]]

I also know I can also use:

def subtract(x):
    return x - y

tf.map_fn(subtract, X)

But when using the result in graph mode, I get:

ValueError: Unable to broadcast: unknown rank


from TensorFlow broadcasting of RaggedTensor

How to verify that the email is authentic in Firebase?

I need to add to my current code, the necessary functionality and the exact code so that the user must verify the email before logging in.

Now, the user registers and automatically accesses all the functions of the application and its user panel. I want to add the necessary function so that when a user registers, a message is shown telling him that: You must verify your email In this way we ensure that it is a valid email and avoid the registration of SPA users.

I need the user to verify her email to be able to log in, until she does, she can continue using the App as she did, without logging in.

You can see that I did several tests, and other users tried to help me, but we have not achieved what is necessary, since I need to add the functionality to the code that I have now, since it is the only way I know to continue building my application.

The app has registration with Firebase, registered by email and password and I'm using Formik to control the state of the form and Yup to validate.

I have read Firebase documentation about "Send a verification message to a user",

This is the Firebase function:

```
const auth = getAuth();
sendEmailVerification(auth.currentUser)
  .then(() => {
    // Email verification sent!
    // ...
  })
```

The registration system I use now is Mail and Password. The user enters an email, a password, verifies the password and is automatically registered in the application.

I did several tests trying to add sendEmailVerification to my registration system, and for now what I have achieved is that the confirmation email arrives to the user (SPA folder) but the confirmation email arrives after the user already registered and use the app.

It would be necessary that the user could not register until receiving and confirming the "Confirmation Email"

I need a code example that fits my current app, I don't have the knowledge to change all my code, this is the base of my app.

What do I have to do so that this works correctly and the verification email arrives before the user can register? What am I doing wrong in my code?

You can test the project as it is built with Expo:

exp://exp.host/@miguelitolaparra/restaurantes-5-estrellas?release-channel=default

enter image description here

This is the method I'm using to register users:

const formik = useFormik({
    initialValues: initialValues(),
    validationSchema: validationSchema(), // validate the form data
    validateOnChange: false,
    onSubmit: async(formValue) => {
      try { // send the data to Firebase
        const auth = getAuth()
       // sendEmailVerification(auth.currentUser)
        await createUserWithEmailAndPassword(
          auth,
          formValue.email,
          formValue.password
        )
      
       sendEmailVerification(auth.currentUser)

        navigation.navigate(screen.account.account)
      } catch (error) {
        // We use Toast to display errors to the user
        Toast.show({
          type: "error",
          position: "bottom",
          text1: "Failed to register, please try again later",
        })
      }
    },
  })

And I also show you the complete file:

import { useFormik } from 'formik'
import { getAuth, createUserWithEmailAndPassword, sendEmailVerification } from 'firebase/auth'

export function RegisterForm() {
  const [showPassword, setShowPassword] = useState(false)
  const [showRepeatPassword, setShowRepeatPassword] = useState(false)

  const navigation = useNavigation()

  const formik = useFormik({
    initialValues: initialValues(),
    validationSchema: validationSchema(), // validate the form data
    validateOnChange: false,
    onSubmit: async (formValue) => {
      try { // send the data to Firebase
        const auth = getAuth()
        //sendEmailVerification(auth.currentUser)
        await createUserWithEmailAndPassword(
          auth,
          formValue.email,
          formValue.password
        )
      sendEmailVerification(auth.currentUser)

       
        navigation.navigate(screen.account.account)
      } catch (error) {
        // We use Toast to display errors to the user
        Toast.show({
          type: "error",
          position: "bottom",
          text1: "Error al registrarse, intentelo mas tarde",
        })
      }
    },
  })

  // function to hide or show the password
  const showHidenPassword = () => setShowPassword((prevState) => !prevState)
  const showHidenRepeatPassword = () => setShowRepeatPassword((prevState) => !prevState)

  return (
    // Registration form interface
    <View>
      <Input
        placeholder="Correo electronico"
        keyboardType="email-address"
        containerStyle={AuthStyles.input}
        rightIcon={
          <Icon type="material-community" name="at" iconStyle={AuthStyles.icon} />
        }
        onChangeText={(text) => formik.setFieldValue("email", text)}
        errorMessage={formik.errors.email}
      />
      <Input
        placeholder="Contraseña"
        containerStyle={AuthStyles.input}
        secureTextEntry={showPassword ? false : true}
        rightIcon={
          <Icon
            type="material-community"
            name={showPassword ? "eye-off-outline" : "eye-outline"}
            iconStyle={AuthStyles.icon}
            onPress={showHidenPassword}
          />
        }
        onChangeText={(text) => formik.setFieldValue("password", text)}
        errorMessage={formik.errors.password}
      />
      <Input
        placeholder="Repetir contraseña"
        containerStyle={AuthStyles.input}
        secureTextEntry={showRepeatPassword ? false : true}
        rightIcon={
          <Icon
            type="material-community"
            name={showRepeatPassword ? "eye-off-outline" : "eye-outline"}
            iconStyle={AuthStyles.icon}
            onPress={showHidenRepeatPassword}
          />
        }
        onChangeText={(text) => formik.setFieldValue("repeatPassword", text)}
        errorMessage={formik.errors.repeatPassword}
      />
      <Button
        title="REGISTRATE"
        containerStyle={AuthStyles.btnContainer}
        buttonStyle={AuthStyles.btn}
        onPress={formik.handleSubmit} // send the form
        loading={formik.isSubmitting}// show loading while doing user registration
      />
    </View>
  )
}

And this is the file to validate the form with Yup RegistreFormValidar.js

import * as Yup from "yup"

// object that has the elements of the form
export function initialValues() {
  return {
    email: "",
    password: "",
    repeatPassword: "",
  }
}

// validate the form data whit Yup
export function validationSchema() {
  return Yup.object({
    email: Yup.string()
      .email("El email no es correcto")
      .required("El email es obligatorio"),
    password: Yup.string().required("La contraseña es obligatoria"),
  
    repeatPassword: Yup.string()  // validate that the passwords are the same
      .required("La contraseña es obligatoria")
      .oneOf([Yup.ref("password")], "Las contraseñas tienen que ser iguales"),
  })
}


from How to verify that the email is authentic in Firebase?

Chunking API response cuts off required data

I am reading chunks of data that is an API response using the following code:

d = zlib.decompressobj(zlib.MAX_WBITS|16)  # for gzip
for i in range(0, len(data), 4096):
    chunk = data[i:i+4096]
    # print(chunk)
    str_chunk = d.decompress(chunk)
    str_chunk = str_chunk.decode()
    # print(str_chunk)
    if '"@odata.nextLink"' in str_chunk:
        ab = '{' + str_chunk[str_chunk.index('"@odata.nextLink"'):len(str_chunk)+1]
        ab = ast.literal_eval(ab)
        url = ab['@odata.nextLink']
        return url

An example of this working is: "@odata.nextLink":"someurl?$count=true

It works in most cases but sometimes this key value pair gets cut off and it appears something like this: "@odata.nextLink":"someurl?$coun

I can play around with the number of bits in this line for i in range(0, len(data), 4096) but that doesn't ensure that in some cases the data doesn't cut off as the page sizes (data size) can be different for each page size.

How can I ensure that this key value pair is never cut off. Also, note that this key value pair is the last line/ last key-value pair of the API response.

P.S.: I can't play around with API request parameters.

Even tried reading it backwards but this gives a header incorrect issue:

for i in range(len(data), 0, -4096):
                chunk = data[i -4096: i]
                str_chunk = d.decompress(chunk)
                str_chunk = str_chunk.decode()
                if '"@odata.nextLink"' in str_chunk:
                    ab = '{' + str_chunk[str_chunk.index('"@odata.nextLink"'):len(str_chunk)+1]
                    ab = ast.literal_eval(ab)
                    url = ab['@odata.nextLink']
                    #print(url)
                    return url

The above produces the following error which is really strange:

str_chunk = d.decompress(chunk)
zlib.error: Error -3 while decompressing data: incorrect header check


from Chunking API response cuts off required data

Mongo DB Realm - java.lang.ExceptionInInitializerError

I’m trying to setup and use Realm Sync with my Android Application. This is the function that I’ve written in order to try and open up the realm, but I’m getting this ExceptionInInitializer Error. Is there any specific code that I need to trigger to initialize Realm before calling this code:

private fun openSyncRealm() {
    val app = App.create(APP_ID)
    runBlocking {
        try {
            val user = app.currentUser
            val config = SyncConfiguration.Builder(
                user = user!!,
                partitionValue = "123456789",
                schema = setOf(AuthenticatedUser::class)
            ).name(name = "user").build()
            val realm = Realm.open(config)
            Log.d("PreparationScreen", "Successfully opened realm: ${realm.configuration.name}")
        } catch (e: Exception) {
            Log.d("PreparationScreen", "$e")
        }
    }
}

And this is my RealmObject subclass:

class AuthenticatedUser: RealmObject {
    @PrimaryKey
    val _id: ObjectId = ObjectId.create()
    var _partition: String = "userId=$_id"
    var name: String = ""
}

Config Builder is causing the error:

java.lang.ExceptionInInitializerError at java.lang.reflect.Field.get(Native Method) at kotlin.reflect.jvm.internal.KClassImpl$Data$objectInstance$2.invoke(KClassImpl.kt:117) at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(ReflectProperties.java:63) at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) at kotlin.reflect.jvm.internal.KClassImpl$Data.getObjectInstance(KClassImpl.kt:108) at kotlin.reflect.jvm.internal.KClassImpl.getObjectInstance(KClassImpl.kt:242) at kotlin.reflect.full.KClasses.getCompanionObjectInstance(KClasses.kt:57) at io.realm.kotlin.internal.platform.RealmObjectKt.realmObjectCompanionOrNull(RealmObject.kt:27) at io.realm.kotlin.Configuration$SharedBuilder.(Configuration.kt:389) at io.realm.kotlin.mongodb.sync.SyncConfiguration$Builder.(SyncConfiguration.kt:213) at io.realm.kotlin.mongodb.sync.SyncConfiguration$Builder.(SyncConfiguration.kt:313) at com.example.feature.authentication.presentation.preparation.PreparationScreenKt$openSyncRealm$1.invokeSuspend(PreparationScreen.kt:61)



from Mongo DB Realm - java.lang.ExceptionInInitializerError

Tuesday 30 August 2022

Implement live markdown rendering using slate.js

I'm writing a markdown text editor using slate.js. I'm trying to implement the following live-rendering effect (from Typora):

Live Markdown rendering

As you can see,

  1. When I'm typing, the text is turning to bold automatically.
  2. When I hit the space key, the four asterisks disappeared, only the text itself is visible.
  3. When I focus the cursor back to the text, the asterisks shows up again (so I can modify them).

I've already implemented the first item thanks to the example of MarkdownPreview, here is the code of it (take from the slate repository):

import Prism from 'prismjs'
import React, { useCallback, useMemo } from 'react'
import { Slate, Editable, withReact } from 'slate-react'
import { Text, createEditor, Descendant } from 'slate'
import { withHistory } from 'slate-history'
import { css } from '@emotion/css'

// eslint-disable-next-line
;Prism.languages.markdown=Prism.languages.extend("markup",{}),Prism.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},code:[{pattern:/^(?: {4}|\t).+/m,alias:"keyword"},{pattern:/``.+?``|`[^`\n]+`/,alias:"keyword"}],title:[{pattern:/\w+.*(?:\r?\n|\r)(?:==+|--+)/,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#+.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])([\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:/(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^\*\*|^__|\*\*$|__$/}},italic:{pattern:/(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^[*_]|[*_]$/}},url:{pattern:/!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,inside:{variable:{pattern:/(!?\[)[^\]]+(?=\]$)/,lookbehind:!0},string:{pattern:/"(?:\\.|[^"\\])*"(?=\)$)/}}}}),Prism.languages.markdown.bold.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.italic.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.bold.inside.italic=Prism.util.clone(Prism.languages.markdown.italic),Prism.languages.markdown.italic.inside.bold=Prism.util.clone(Prism.languages.markdown.bold); // prettier-ignore

const MarkdownPreviewExample = () => {
  const renderLeaf = useCallback(props => <Leaf {...props} />, [])
  const editor = useMemo(() => withHistory(withReact(createEditor())), [])
  const decorate = useCallback(([node, path]) => {
    const ranges = []

    if (!Text.isText(node)) {
      return ranges
    }

    const getLength = token => {
      if (typeof token === 'string') {
        return token.length
      } else if (typeof token.content === 'string') {
        return token.content.length
      } else {
        return token.content.reduce((l, t) => l + getLength(t), 0)
      }
    }

    const tokens = Prism.tokenize(node.text, Prism.languages.markdown)
    let start = 0

    for (const token of tokens) {
      const length = getLength(token)
      const end = start + length

      if (typeof token !== 'string') {
        ranges.push({
          [token.type]: true,
          anchor: { path, offset: start },
          focus: { path, offset: end },
        })
      }

      start = end
    }

    return ranges
  }, [])

  return (
    <Slate editor={editor} value={initialValue}>
      <Editable
        decorate={decorate}
        renderLeaf={renderLeaf}
        placeholder="Write some markdown..."
      />
    </Slate>
  )
}

const Leaf = ({ attributes, children, leaf }) => {
  return (
    <span
      {...attributes}
      className={css`
        font-weight: ${leaf.bold && 'bold'};
        font-style: ${leaf.italic && 'italic'};
        text-decoration: ${leaf.underlined && 'underline'};
        ${leaf.title &&
          css`
            display: inline-block;
            font-weight: bold;
            font-size: 20px;
            margin: 20px 0 10px 0;
          `}
        ${leaf.list &&
          css`
            padding-left: 10px;
            font-size: 20px;
            line-height: 10px;
          `}
        ${leaf.hr &&
          css`
            display: block;
            text-align: center;
            border-bottom: 2px solid #ddd;
          `}
        ${leaf.blockquote &&
          css`
            display: inline-block;
            border-left: 2px solid #ddd;
            padding-left: 10px;
            color: #aaa;
            font-style: italic;
          `}
        ${leaf.code &&
          css`
            font-family: monospace;
            background-color: #eee;
            padding: 3px;
          `}
      `}
    >
      {children}
    </span>
  )
}

const initialValue: Descendant[] = [
  {
    type: 'paragraph',
    children: [
      {
        text:
          'Slate is flexible enough to add **decorations** that can format text based on its content. For example, this editor has **Markdown** preview decorations on it, to make it _dead_ simple to make an editor with built-in Markdown previewing.',
      },
    ],
  },
  {
    type: 'paragraph',
    children: [{ text: '## Try it out!' }],
  },
  {
    type: 'paragraph',
    children: [{ text: 'Try it out for yourself!' }],
  },
]

export default MarkdownPreviewExample

My question is, how can I implement the second and third items? I've been thinking about it for a long time, but didn't find any good way to achieve them.



from Implement live markdown rendering using slate.js

JEST testPathPattern not recognizing integration tests

I have the below structure and trying to run jest --testPathPattern=static/integration-tests to execute only the integration-tests. But I am seeing 0 matches. I tried even testRegex and other options too but in vain. Is my command right or is any modification required? FYI jest documentation doesn't have much description on the file patterns and I am completely new to the Javascript and ofcourse the Jest. Appreciate any help!

-resources
   |__package.json
   |__static
          |__unit-tests
          |          |__somescript.unit.test.js
          |
          |__integration-tests
                     |__somescript.int.test.js  


from JEST testPathPattern not recognizing integration tests

Mermaid JS wrap links from far right to far left

Working with Mermaid js to make flowcharts and can't seem to find a way to wrap links around to a new "line" so to speak. Docs and Googling haven't gotten me anywhere. Does anyone know if it is possible to create a link to replace the red line?

enter image description here



from Mermaid JS wrap links from far right to far left

How to download files from website using PHP with Python

I have a Python script that crawls various webistes and downloads files form them. My problem is, that some of the websites seem to be using PHP, at least that's my theory since the URLs look like this: https://www.portablefreeware.com/download.php?dd=1159

The problem is that I can't get any file names or endings from a link like this and therefore can't save the file. Currently I'm only saving the URLs.

Is there any way to get to the actual file name behind the link?

This is my stripped down download code:

r = requests.get(url, allow_redirects=True)

file = open("name.something", 'wb')
file.write(r.content)
file.close()

Disclaimer: I've never done any work with PHP so please forgive any incorrect terminolgy or understanding I have of that. I'm happy to learn more though



from How to download files from website using PHP with Python

Is there a need to use atomics or other synchronization

I'm new to Compose and Android development in general. While building a toy project with Compose, I faced a question. I need to load ~100 short sounds from assets to play them via SoundPool. SoundPool.load() loads asynchronously I suppose (otherwise why do we need a callback).

Code in viewmodel:

    private val TAG = javaClass.simpleName

    private val soundPool: SoundPool
    private val soundsInProgress = AtomicInteger(0)

    var sounds: List<Sound> by mutableStateOf(listOf())
        private set


    init {
        val audioAttributes = AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
            .build()
        soundPool = SoundPool.Builder()
            .setMaxStreams(3)
            .setAudioAttributes(audioAttributes)
            .build()
        loadSoundsFromAssets()
    }

    private fun loadSoundsFromAssets() {
        val assetManager = getApplication<MyApp>().applicationContext.assets
        val sounds = assetManager.list("sounds/")!!.map(this::parseSound)
        soundsInProgress.set(sounds.size)
        soundPool.setOnLoadCompleteListener { _, id, status ->
            if (status == 0) {
                val left = soundsInProgress.decrementAndGet()
                Log.i(TAG, "Loaded 1 sound, $left in progress")
                if (left == 0) {
                    sounds = sounds
                }
            } else {
                Log.e(TAG, "Could not load sound $id, status is $status")
            }
        }
        sounds.forEach {
            val soundId = soundPool.load(assetManager.openFd("sounds/" + it.fileName), 0)
            it.soundId = soundId
        }
    }

My aim here is to track progress of sound preloading.

The question is: Is it overkill to use atomic here or is it safe without atomic?

Also, how do I observe changes to soundsInProgress ? MutableState won't work as expected.



from Is there a need to use atomics or other synchronization

Sunday 28 August 2022

How can I create app icon when I use Android Studio Chipmunk | 2021.2.1?

I have read the articles about creating app icon, such as What's mipmap-anydpi-v26 in res directory in Android Studio 3.0? and Create app icons with Image Asset Studio.

When I create a project with latest Android Studio Chipmunk | 2021.2.1, the wizard of Android Studio will generate the default app icon automatically.

I know I can use Image Asset Studio to create myself app icon, so I select a file .svg file and try to generate it, you can see Image 1, and Image 2

When I check these generated icons, I found the extension name of my files is .png, but the the extension name of files which is generated by the wizard is .webp, you can see Image 3.

I don't know if there is new way to create app icon, could you tell me ?

Image 1 enter image description here

Image 2 enter image description here

Image 3

enter image description here



from How can I create app icon when I use Android Studio Chipmunk | 2021.2.1?

Android : how to convert back openCV Mat to byte array NV21?

On Android , I use MediaCodec to create mp4 video file from captured images.

I am getting the OpenCV Mat data using

Image i = reader.acquireLatestImage();
ByteBuffer byteBuffer = i.getPlanes()[0].getBuffer();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
Mat mImageGrab = Imgcodecs.imdecode(new MatOfByte(bytes), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED); <= bytes from Image object

I have checked and the bitmap images are correctly showing(with some colors wrong translation)

this is the code that tests the Bitmaps:

Mat nv21 = new Mat();
Imgproc.cvtColor(mImageGrab, nv21, Imgproc.COLOR_RGB2YUV_I420);<= NV21 is mat was created
Bitmap bmp = Bitmap.createBitmap(mImageGrab.cols(), mImageGrab.rows(), Bitmap.Config.ARGB_8888);
Mat bmpMat = new Mat();
Imgproc.cvtColor(nv21,bmpMat, Imgproc.COLOR_YUV420sp2RGB);<= transfer NV21 to Bitmap
Utils.matToBitmap(bmpMat, bmp);<= great bitmap result

However the MediaCodec mp4 expects byte array of NV21 image and not bitmap. How can I transform the Mat to NV21? or the bitmap to NV21? I want to perform some image processing to the images before sending those images to the MediaCodec.

I can also use the "encodeYUV420SP" function that was mentioned here Link to encode NV21 but it is too slow for video.

other option - render scripts - support for those supposes to be deprecated - so - I prefer not to. But I am ready to try : bitmap to NV21 render script that is androidx compatible.()



from Android : how to convert back openCV Mat to byte array NV21?

What makes this use of jScroll in a Laravel 8 application fail?

I am working on a blogging application in Laravel 8.

The ArticlesController controller I have this method to display the single article and its comments:

class ArticlesController extends FrontendController {

    // More code

    public function show($slug) {
        // Single article
        $article = Article::firstWhere('slug', $slug);
        $old_article = Article::where('id', '<', $article->id)->orderBy('id', 'DESC')->first();
        $new_article = Article::where('id', '>', $article->id)->orderBy('id', 'ASC')->first();

        // Comments
        $commentsQuery = Comment::where(['article_id' => $article->id, 'approved' => 1])->orderBy('id', 'desc');
        $comments = $commentsQuery->paginate(10);
        $comments_count = $commentsQuery->count();

        return view('themes/' . $this->theme_directory . '/templates/single', 
            array_merge($this->data, [
                'categories' => $this->article_categories,
                'article' => $article,
                'old_article' => $old_article,
                'new_article' => $new_article,
                'comments' => $comments,
                'comments_count' => $comments_count,
                'tagline' => $article->title,
                ])
            );
    }

}

In the view I have this for the comments list:

<div id="commentsList">
  <ol class="commentlist">
    @foreach ($comments as $comment)
    <li class="depth-1 comment">
      <div class="comment__avatar">
        <img class="avatar" src="" alt="" width="50" height="50">
      </div>
      <div class="comment__content">
        <div class="comment__info">
          <div class="comment__author"> </div>
          <div class="comment__meta">
            <div class="comment__time"></div>
            <div class="comment__reply">
              <a class="comment-reply-link" href="#0">Reply</a>
            </div>
          </div>
        </div>
        <div class="comment__text">
          <p></p>
        </div>
      </div>
    </li>
    @endforeach
  </ol>

  
</div>

The goal

I want to replace the comments pagination with an "infinite scroll", with the help of jScroll.

For this purpose, I have:

$('#commentsList nav').hide();
$(function() {
    $('#commentsList').jscroll({
        autoTrigger: true,
        loadingHtml: '<span>Loading...</span>',
        padding: 0,
        nextSelector: '.pagination li.active + li a',
        contentSelector: '.commentlist > li',
        callback: function() {
            $('#commentsList nav').remove();
        }
    });
});

The problem

The code above should append the <li class="depth-1 comment"></li> elements to the <ol class="commentlist"><ol> but instead it does the folowing:

  • wraps the loaded list items in a <div class="jscroll-added"></div>
  • puts the <div class="jscroll-added"></div> element below the comments list instead of inside it.

Questions

  1. What causes this bug?
  2. What is the easiest fix?


from What makes this use of jScroll in a Laravel 8 application fail?

Package requirement 'psycopg2==2.9.1' not satisfied pycharm macos

after long hours of trying: i installed psycopg2==2.9.1 with pip installed with pip

I tried adding it to all the interpreter paths i could find but still keep getting this message: error message

I tried as well restarting pycharm, invalidate caches ..

When trying to just install it with pycharm i get this error messege:

    Collecting psycopg2==2.9.1
  Using cached psycopg2-2.9.1.tar.gz (379 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Building wheels for collected packages: psycopg2
  Building wheel for psycopg2 (setup.py): started
  Building wheel for psycopg2 (setup.py): finished with status 'error'
  Running setup.py clean for psycopg2
Failed to build psycopg2
Installing collected packages: psycopg2
    Running setup.py install for psycopg2: started
    Running setup.py install for psycopg2: finished with status 'error'

  ERROR: Command errored out with exit status 1:
   command: '/Users/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/data_index-development/venv/bin/python' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-install-myo1zngt/psycopg2_e9a9698f63464cb99bc5bf3655675aa2/setup.py'"'"'; __file__='"'"'/private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-install-myo1zngt/psycopg2_e9a9698f63464cb99bc5bf3655675aa2/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-wheel-lbvr1lzp
       cwd: /private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-install-myo1zngt/psycopg2_e9a9698f63464cb99bc5bf3655675aa2/
  Complete output (53 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.macosx-10.13.0-x86_64-3.9
  creating build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/_json.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/extras.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/errorcodes.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/tz.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/_range.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/_ipaddress.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/__init__.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/extensions.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/errors.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/sql.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  copying lib/pool.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
  warning: build_py: byte-compiling is disabled, skipping.
  
  running build_ext
  building 'psycopg2._psycopg' extension
  creating build/temp.macosx-10.13.0-x86_64-3.9
  creating build/temp.macosx-10.13.0-x86_64-3.9/psycopg
  /usr/bin/clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -I/MISSING/DEPS//stage/include -I/MISSING/DEPS//stage/unixodbc/include -I/MISSING/DEPS//stage/include -I/MISSING/DEPS//stage/unixodbc/include -DPSYCOPG_VERSION=2.9.1 (dt dec pq3 ext lo64) -DPSYCOPG_DEBUG=1 -DPG_VERSION_NUM=140001 -DHAVE_LO64=1 -DPSYCOPG_DEBUG=1 -I/Users/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/data_index-development/venv/include -I/Applications/QGIS.app/Contents/MacOS/include/python3.9 -I. -I/opt/homebrew/include -I/opt/homebrew/include/postgresql/server -I/opt/homebrew/Cellar/icu4c/69.1/include -I/opt/homebrew/opt/openssl@1.1/include -I/opt/homebrew/opt/readline/include -c psycopg/adapter_asis.c -o build/temp.macosx-10.13.0-x86_64-3.9/psycopg/adapter_asis.o
  In file included from psycopg/adapter_asis.c:28:
  ./psycopg/psycopg.h:35:10: error: 'Python.h' file not found with <angled> include; use "quotes" instead
  #include <Python.h>
           ^~~~~~~~~~
           "Python.h"
  ./psycopg/psycopg.h:35:10: warning: non-portable path to file '<python.h>'; specified path differs in case from file name on disk [-Wnonportable-include-path]
  #include <Python.h>
           ^~~~~~~~~~
           <python.h>
  In file included from psycopg/adapter_asis.c:28:
  In file included from ./psycopg/psycopg.h:35:
  psycopg/Python.h:31:2: error: "psycopg requires Python 3.6"
  #error "psycopg requires Python 3.6"
   ^
  psycopg/Python.h:34:10: fatal error: 'structmember.h' file not found
  #include <structmember.h>
           ^~~~~~~~~~~~~~~~
  1 warning and 3 errors generated.
  
  It appears you are missing some prerequisite to build the package from source.
  
  You may install a binary package by installing 'psycopg2-binary' from PyPI.
  If you want to install psycopg2 from source, please install the packages
  required for the build and try again.
  
  For further information please check the 'doc/src/install.rst' file (also at
  <https://www.psycopg.org/docs/install.html>).
  
  error: command '/usr/bin/clang' failed with exit code 1
  ----------------------------------------
  ERROR: Failed building wheel for psycopg2
    ERROR: Command errored out with exit status 1:
     command: '/Users/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/data_index-development/venv/bin/python' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-install-myo1zngt/psycopg2_e9a9698f63464cb99bc5bf3655675aa2/setup.py'"'"'; __file__='"'"'/private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-install-myo1zngt/psycopg2_e9a9698f63464cb99bc5bf3655675aa2/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-record-fkjtibr5/install-record.txt --single-version-externally-managed --compile --install-headers '/Users/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/data_index-development/venv/include/site/python3.9/psycopg2'
         cwd: /private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-install-myo1zngt/psycopg2_e9a9698f63464cb99bc5bf3655675aa2/
    Complete output (55 lines):
    running install
    /Users/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/data_index-development/venv/lib/python3.9/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    running build
    running build_py
    creating build
    creating build/lib.macosx-10.13.0-x86_64-3.9
    creating build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/_json.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/extras.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/errorcodes.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/tz.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/_range.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/_ipaddress.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/__init__.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/extensions.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/errors.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/sql.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    copying lib/pool.py -> build/lib.macosx-10.13.0-x86_64-3.9/psycopg2
    warning: build_py: byte-compiling is disabled, skipping.
    
    running build_ext
    building 'psycopg2._psycopg' extension
    creating build/temp.macosx-10.13.0-x86_64-3.9
    creating build/temp.macosx-10.13.0-x86_64-3.9/psycopg
    /usr/bin/clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -I/MISSING/DEPS//stage/include -I/MISSING/DEPS//stage/unixodbc/include -I/MISSING/DEPS//stage/include -I/MISSING/DEPS//stage/unixodbc/include -DPSYCOPG_VERSION=2.9.1 (dt dec pq3 ext lo64) -DPSYCOPG_DEBUG=1 -DPG_VERSION_NUM=140001 -DHAVE_LO64=1 -DPSYCOPG_DEBUG=1 -I/Users/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/data_index-development/venv/include -I/Applications/QGIS.app/Contents/MacOS/include/python3.9 -I. -I/opt/homebrew/include -I/opt/homebrew/include/postgresql/server -I/opt/homebrew/Cellar/icu4c/69.1/include -I/opt/homebrew/opt/openssl@1.1/include -I/opt/homebrew/opt/readline/include -c psycopg/adapter_asis.c -o build/temp.macosx-10.13.0-x86_64-3.9/psycopg/adapter_asis.o
    In file included from psycopg/adapter_asis.c:28:
    ./psycopg/psycopg.h:35:10: error: 'Python.h' file not found with <angled> include; use "quotes" instead
    #include <Python.h>
             ^~~~~~~~~~
             "Python.h"
    ./psycopg/psycopg.h:35:10: warning: non-portable path to file '<python.h>'; specified path differs in case from file name on disk [-Wnonportable-include-path]
    #include <Python.h>
             ^~~~~~~~~~
             <python.h>
    In file included from psycopg/adapter_asis.c:28:
    In file included from ./psycopg/psycopg.h:35:
    psycopg/Python.h:31:2: error: "psycopg requires Python 3.6"
    #error "psycopg requires Python 3.6"
     ^
    psycopg/Python.h:34:10: fatal error: 'structmember.h' file not found
    #include <structmember.h>
             ^~~~~~~~~~~~~~~~
    1 warning and 3 errors generated.
    
    It appears you are missing some prerequisite to build the package from source.
    
    You may install a binary package by installing 'psycopg2-binary' from PyPI.
    If you want to install psycopg2 from source, please install the packages
    required for the build and try again.
    
    For further information please check the 'doc/src/install.rst' file (also at
    <https://www.psycopg.org/docs/install.html>).
    
    error: command '/usr/bin/clang' failed with exit code 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: '/Users//Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/data_index-development/venv/bin/python' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-install-myo1zngt/psycopg2_e9a9698f63464cb99bc5bf3655675aa2/setup.py'"'"'; __file__='"'"'/private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-install-myo1zngt/psycopg2_e9a9698f63464cb99bc5bf3655675aa2/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /private/var/folders/fj/blrljwxs22q3csr4fqw7ycmc0000gn/T/pip-record-fkjtibr5/install-record.txt --single-version-externally-managed --compile --install-headers '/Users/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/data_index-development/venv/include/site/python3.9/psycopg2' Check the logs for full command output.

What can fix it?



from Package requirement 'psycopg2==2.9.1' not satisfied pycharm macos

This error is coming while doing intent Cannot resolve method 'putExtra(java.lang.String,

How do I use range breaks and scattergl in the same plot?

I have this plot-

fig = go.Figure()

fig.add_trace(
    go.Scattergl(x=list(df.Date), y=list(df.Measure)), row = 1, col = 1)
    
fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     label="1m",
                     step="month",
                     stepmode="backward")
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
        type="date"
    )
)

The code works fine when I remove the range-breaks, but stops working when I add them in.

Is it possible to use range breaks and scatter gl in the same plot?



from How do I use range breaks and scattergl in the same plot?

What input event can I fire when someone clicks on a custom button?

I have this plot-

import plotly.graph_objects as go

import pandas as pd

# load dataset
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/volcano.csv")

# create figure
fig = go.Figure()

# Add surface trace
fig.add_trace(go.Surface(z=df.values.tolist(), colorscale="Viridis"))

# Update plot sizing
fig.update_layout(
    width=800,
    height=900,
    autosize=False,
    margin=dict(t=0, b=0, l=0, r=0),
    template="plotly_white",
)

# Update 3D scene options
fig.update_scenes(
    aspectratio=dict(x=1, y=1, z=0.7),
    aspectmode="manual"
)

# Add dropdown
fig.update_layout(
    updatemenus=[
        dict(
            type = "buttons",
            direction = "left",
            buttons=list([
                dict(
                    args=["type", "surface"],
                    label="3D Surface",
                    method="restyle"
                ),
                dict(
                    args=["type", "heatmap"],
                    label="Heatmap",
                    method="restyle"
                )
            ]),
            pad={"r": 10, "t": 10},
            showactive=True,
            x=0.11,
            xanchor="left",
            y=1.1,
            yanchor="top"
        ),
    ]
)

# Add annotation
fig.update_layout(
    annotations=[
        dict(text="Trace type:", showarrow=False,
                             x=0, y=1.08, yref="paper", align="left")
    ]
)

fig.show()

I want to update the chart whenever someone clicks on either of the two buttons. I need to connect the update code to some event. If it was changing the x-axis, for example, I could use the relayout_data event. Is there any event that gets fired when someone clicks a custom button that I can tie to an Input() callback?



from What input event can I fire when someone clicks on a custom button?

Saturday 27 August 2022

streamlit AgGrid deleting row doesnt refresh data in the backend

I have two AgGrid's in python streamlit application. Two AgGrid's are connected and GridUpdateMode.MANUAL . I have to select rows in first grid and click on update so that second grid will get selected rows from first grid. the rows in second grid should be process and saved. but, I have to also delete rows from second grid. deletion of rows from second grid is implemented with onRowSelected.

Problem:

The javascript code which is injected with onRowSelected works and removes the row from UI but, the python variable which has the data is not update or the rows which are removed from UI are not removed from actual variable.

Please help me in how to remove the row when selected from UI and also in backend variable.

Code:

js = JsCode(
"""
function(e) {
    let api = e.api;        
    let sel = api.getSelectedRows();

    const res = api.updateRowData({remove: sel});
    api.refreshCells({force : true});

    };
"""
)


    col1, col2 = st.columns(2)
    with st.container():
    with col1:
        smoke_gd = GridOptionsBuilder.from_dataframe(
            df_alternatives[["article", "number"]]
        )
        smoke_gd.configure_default_column(
            editable=False, resizable=True, sorteable=True
        )
        smoke_gd.configure_pagination(enabled=True)
        smoke_gd.configure_side_bar()
        smoke_gd.configure_selection(
            selection_mode="multiple", use_checkbox=True
        )
        smoke_gd_gridoptions = smoke_gd.build()
        smoke_grid_table = AgGrid(
            df_alternatieven[["article", "number"]],
            fit_columns_on_grid_load=True,
            update_mode=GridUpdateMode.MANUAL,
            gridOptions=smoke_gd_gridoptions,
            enable_enterprise_modules=True,
            allow_unsafe_jscode=True,
            theme="fresh",
            key="smoke_col1_gd",

        )
    selected_rows = smoke_grid_table["selected_rows"]

    with col2:
        smoke_col2_gd = GridOptionsBuilder.from_dataframe(
            df_alternatives[["article", "number"]]
        )
        smoke_col2_gd.configure_default_column(
            editable=False, resizable=True, sorteable=True
        )
        smoke_col2_gd.configure_pagination(enabled=True)

        smoke_col2_gd.configure_grid_options(onRowSelected=js)
        smoke_col2_gd.configure_side_bar()
        smoke_col2_gd.configure_selection(
            selection_mode="multiple", use_checkbox=True
        )
        smoke_col2_gd_gridoptions = smoke_col2_gd.build()
        smoke_grid_table_filtered = AgGrid(
            pd.DataFrame(selected_rows),
            update_mode=GridUpdateMode.MANUAL,
            gridOptions=smoke_col2_gd_gridoptions,
            allow_unsafe_jscode=True,
            reload_data=True,
            key="smoke_col2_gd",
        )


from streamlit AgGrid deleting row doesnt refresh data in the backend

Apply function to dataframe row use result for next row input

I am trying to create a rudimentary scheduling system. Here is what I have so far:

I have a pandas dataframe job_data that looks like this:

wc job start duration
1 J1 2022-08-16 07:30:00 17
1 J2 2022-08-16 07:30:00 5
2 J3 2022-08-16 07:30:00 21
2 J4 2022-08-16 07:30:00 12

It contains a wc (work center), job, a start date and duration for the job in hours.

I have created a function add_hours that takes the following arguments: start (datetime), hours (int).

It calculates the when the job will be complete based on the start time and duration.

The code for add_hours is:

def is_in_open_hours(dt):
    return (
        dt.weekday() in business_hours["weekdays"]
        and dt.date() not in holidays
        and business_hours["from"].hour <= dt.time().hour < business_hours["to"].hour
    )


def get_next_open_datetime(dt):
    while True:
        dt = dt + timedelta(days=1)
        if dt.weekday() in business_hours["weekdays"] and dt.date() not in holidays:
            dt = datetime.combine(dt.date(), business_hours["from"])
            return dt


def add_hours(dt, hours):
    while hours != 0:
        if is_in_open_hours(dt):
            dt = dt + timedelta(hours=1)
            hours = hours - 1
        else:
            dt = get_next_open_datetime(dt)
    return dt

The code to calculate the end column is:

df["end"] = df.apply(lambda x: add_hours(x.start, x.duration), axis=1)

The result of function is the end column:

wc job start duration end
1 J1 2022-08-16 07:30:00 17 2022-08-17 14:00:00
1 J2 2022-08-16 07:30:00 5 2022-08-17 10:00:00
2 J3 2022-08-16 07:30:00 21 2022-08-18 08:00:00
2 J4 2022-08-16 07:30:00 12 2022-08-18 08:00:00

Problem is, I need the start datetime in the second row to be the end datetime from the previous row instead of them all using the same start date. I also need to start this process over for each wc.

So the desired output would be:

wc job start duration end
1 J1 2022-08-16 07:30:00 17 2022-08-17 14:00:00
1 J2 2022-08-17 14:00:00 5 2022-08-17 19:00:00
2 J3 2022-08-16 07:30:00 21 2022-08-18 08:00:00
2 J4 2022-08-18 08:00:00 10 2022-08-18 18:00:00


from Apply function to dataframe row use result for next row input

NullPointerException at ActivityTransitionCoordinator.checkMatrixAgain Xiaomi with Android 12

Getting a lot of crashes when starting an activity for Xiaomi devices with Android 12 here is the crash log:

Fatal Exception: java.lang.NullPointerException: Attempt to read from field 'int android.graphics.Rect.left' on a null object reference
   at android.app.ActivityTransitionCoordinator.checkMatrixAgain(ActivityTransitionCoordinator.java:897)
   at android.app.ActivityTransitionCoordinator.moveSharedElementsToOverlay(ActivityTransitionCoordinator.java:878)
   at android.app.ExitTransitionCoordinator.startExit(ExitTransitionCoordinator.java:210)
   at android.app.ActivityTransitionState.startExitOutTransition(ActivityTransitionState.java:393)
   at android.app.Activity.cancelInputsAndStartExitTransition(Activity.java:5550)
   at android.app.Activity.startActivityForResult(Activity.java:5526)
   at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:675)
   at com.sample.myApp.MainActivity$4.onClick(MainActivity.java:222)

this log reported on every place I start for activity the crash above happens through this click

      public void onClick(View v) {
    Intent editIntent = new Intent(MainActivity.this, EditActivity.class);
    editIntent.putExtra(EDITING, true);
    startActivityForResult(editIntent, EDIT_REQUEST);
  }

Crashlytics report



from NullPointerException at ActivityTransitionCoordinator.checkMatrixAgain Xiaomi with Android 12

Vue 3 CKEditor 5 Add Plugins CodeBlock Error Duplicate Module

I am trying to add CodeBlock plugin tu my editor, here is my component

<script setup>
    import { ref, reactive } from 'vue'
    import CKEditor from '@ckeditor/ckeditor5-vue'
    import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
    import CodeBlock from '@ckeditor/ckeditor5-code-block/src/codeblock'

    const editor = ClassicEditor
    const ckeditor = CKEditor.component
    const editorConfig = {plugins :[CodeBlock]}
    const data = reactive({
        title :"judulnya",
        content:'<b>Isi Post ni bos</b>'
    })
    const submitPost = ()=>{
        let form = {...data}
        console.log(form)
    }
</script>
<template>
   <div class="container-fluid p-0">

        <div class="row">
            <div class="col-12">
                <div class="card">
                    <div class="card-body">
                        <form @submit.prevent="submitPost">
                            <div class="mb-3">
                                <input type="text" v-model="data.title" class="form-control">
                            </div>
                            <div class="mb-3">
                                <ckeditor :config="editorConfig" :editor="editor" v-model="data.content"></ckeditor>
                            </div>
                            <button type="submit" class="btn btn-primary">Post</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div> 
</template>
<style>
.ck-editor__editable {min-height: 50vh;}
</style>

but when compiled i got error CKEditorError: ckeditor-duplicated-modules. I have read the documentation but almost all of the guidance is not in vue 3 style and i can't understand it well. In short term, how to add this plugin depends on my coding style?



from Vue 3 CKEditor 5 Add Plugins CodeBlock Error Duplicate Module

Controlling where sphinx generated .rst files are saved

Suppose the following documentation structure for sphinx:

doc
 |_ _static
 |_ _templates
 |_ api
     |_ index.rst
     |_ classes.rst
     |_ functions.rst
 |_ index.rst
 |_ more_functions.rst
 |_ conf.py

And that classes.rst, functions.rst and more_functions.rst have classes and functions to auto-document with autodoc/autosummary. The build will generate .rst files for those classes and functions in:

  • doc/generated for more_functions.rst
  • doc/api/generated for classes.rst and functions.rst

Is there a way to control where those generated folders are created?


I'm trying to get a unique generated folder in the end. In this case, with this structure:

doc
 |_ generated
     |_ generated-from-more-functions.rst
     |_ api
         |_ generated-from-api/classes.rst
         |_ generated-from-api/functions-rst


from Controlling where sphinx generated .rst files are saved

Friday 26 August 2022

How does Content Security Policy (CSP) work?

I'm getting a bunch of errors in the developer console:

Refused to evaluate a string

Refused to execute inline script because it violates the following Content Security Policy directive

Refused to load the script

Refused to load the stylesheet

What's this all about? How does Content Security Policy (CSP) work? How do I use the Content-Security-Policy HTTP header?

Specifically, how to...

  1. ...allow multiple sources?
  2. ...use different directives?
  3. ...use multiple directives?
  4. ...handle ports?
  5. ...handle different protocols?
  6. ...allow file:// protocol?
  7. ...use inline styles, scripts, and tags <style> and <script>?
  8. ...allow eval()?

And finally:

  1. What exactly does 'self' mean?


from How does Content Security Policy (CSP) work?

Ajax beforeSend sometimes doesn't fire to show bootstrap progress bar

I have 3 Bootstrap tabs, each with a table showing query results. When the search button is clicked, or a tab is changed, an ajax call is triggered that has a beforeSend function which shows a Bootstrap progress bar. The progress bar always shows the first time I load the page, but then is only intermittent after that. I can't seem to figure out when it shows and when it doesn't. The searches can take 5 or 6 seconds, so it's really necessary to have something for the user to know the search is running.

I saw some threads about async:false causing issues in chrome, but I don't have that set and the issue also shows up in Firefox.

I also saw a thread about having the ajax call wrapped in a document.ready, but this code is in a separate .js file?

OK, the function is long. I'm putting the whole thing in case there's some conflict. I tried commenting out the multiple ajax calls in the success function and just running the one with the beforeSend function but the issue still showed up.

Let me know if you have any ideas to troubleshoot or a potential work around...Thank you!

function submitSearch(method) {
  $("#programCount").html('');
  $("#plotCount").html('');
  $("#treeCount").html('');
  checkdata=validate_input();
  if (checkdata===false) {
     return;
  }
  yearLower= $('#startYr').val();
  yearUpper= $('#endYr').val();
   
  var state=[];
  if(!($('.state_sub_checkbox:checkbox:checked').length === $('.state_sub_checkbox').length)){
      $('.state_sub_checkbox:checkbox:checked').each(function() {
                state.push(this.value);
            });
    }
  var TSN=[];
  var treeSpecies=[];
  if (!($('.species_sub_checkbox:checkbox:checked').length===$('.species_sub_checkbox').length)) {
      $('.species_sub_checkbox:checkbox:checked').each(function() {
 //         species.push(this.value);
          TSN.push(this.value);
          treeSpecies.push($(this).closest("label").text().trim());
      });
  }

  var progList=[];
  var progListNames=[];
  if (!($('.program_sub_checkbox:checkbox:checked').length ===$('.program_sub_checkbox').length)) {
      $('.program_sub_checkbox:checkbox:checked').each(function() {
                progList.push(this.value);
                progListNames.push($(this).closest("label").text().trim());
            }); 
    }    
    
  forestHealth =[];
  if (!($('.FHI_checkbox:checkbox:checked').length===$('.FHI_checkbox').length)) {
      $('.FHI_checkbox:checkbox:checked').each(function() {
          forestHealth.push(this.value);
      });
  }
  crown="";
  if (!($('.crown_checkbox:checkbox:checked').length===$('.crown_checkbox').length)) {
      crown=$('input[name="crown"]:checked').val();
  }
  height=[];
  if (!($('.height_checkbox:checkbox:checked').length===$('.height_checkbox').length)) {
      $('.height_checkbox:checkbox:checked').each(function() {
          height.push(this.value);
      });
  }
  
  tree_status=[];
  if (!($('.tree_status:checkbox:checked').length===$('.tree_status').length)) {
      $('.tree_status:checkbox:checked').each(function() {
          tree_status.push(this.value);
      });      
  }
  
  missingDBH = $('#DBH_missing').prop('checked');
  dbhUpper = $('#endDBH').val();
  dbhLower = $('#startDBH').val();
  missingHeight = $('#height_missing').prop('checked');
  heightUpper = $('#endHeight').val();
  heightLower = $('#startHeight').val();

  var limit=10;  
  var offset="";
  if (method==='ajax_getPrograms') {
      fields = ['pkProgramID','fldName','fldOrganization','fldProgramStartDate','fldProgramEndDate','fldStates'];
      limit=$('#num_results').val();
      offset=$('#program_table_offset').val();
    }
  if (method==='ajax_getPlots') {
      fields = ['programID','lat','long','plotSampleYear','_nefin_plotID', '_nefin_plot_obsID'];  
      limit=$('#num_results_plot').val();
      offset=$('#plot_table_offset').val();      
  }  
  if (method==='ajax_getTrees') {
      fields = ['programID','TSN','treeSpecies','DBH','treeStatus','treeSampleYear','_nefin_plotID','_nefin_plot_obsID','_nefin_treeID','_nefin_tree_obsID'];   
      limit=$('#num_results_tree').val();
      offset=$('#tree_table_offset').val();      
  }
  
  var posturl = baseURL + "data/"+method;
  var formData = new FormData();
  if (progList.length>0) {
      formData.append('progList',progList);
      formData.append('progListNames',progListNames);
  }
  if (TSN.length>0) {
      formData.append('TSN', TSN);
      formData.append('treeSpecies', treeSpecies);
  }

  
  if (yearLower!==filters.year_min) {
      formData.append('yearLower', yearLower);

  }
  if (yearUpper!==filters.year_max) {
      formData.append('yearUpper', yearUpper);
  }
  if(!($('.state_sub_checkbox:checkbox:checked').length === $('.state_sub_checkbox').length)){
      formData.append('state', state);
  }
  if (forestHealth.length>0) {
      formData.append('forestHealth',forestHealth);
  }
  if (crown!=="") {
      formData.append('crown',crown);
  }
  if (tree_status.length>0) {
      formData.append('status',tree_status);
  }
  var height_change=false;
  if (heightUpper!==filters.height_max) {
      height_change=true;
      formData.append('heightUpper',heightUpper);
  }
  
  if (heightLower!==filters.height_min) {
      height_change=true;
      formData.append('heightLower',heightLower);
  }
  if (height_change===true || missingHeight===false) {
      formData.append('missingHeight',missingHeight);
  }
  var dbh_change=false;
  if (dbhUpper!==filters.dbh_max) {
      dbh_change=true;
      formData.append('dbhUpper',dbhUpper);
  }
  
  if (dbhLower!==filters.dbh_min) {
      dbh_change=true;
      formData.append('dbhLower',dbhLower);
  }
  if (dbh_change===true || missingDBH===false) {
      formData.append('missingDBH',missingDBH);
  }

   //get options in array for getData variable
  var getData = {};
formData.forEach(function(value, key){
        getData[key] = value;  
});

var getDataJSON = JSON.stringify(getData);

  formData.append('fields',fields);
  formData.append('limit',limit);
  formData.append('offset',offset);
  
updateSearchParamHTML(formData);
  $.ajax({
            url: posturl,
            cache: false,
            data: formData,
            method: 'POST',
            contentType: false,
            processData: false,
            type: 'POST',
            beforeSend: function(){
                $('.progress').show();
                $('.progress-bar').attr('style', 'width: 100%;');

            },
            complete: function(){
                $('.progress').hide();
                $('.progress-bar').attr('style', 'width: 0%;');

            },
            error: function (xhr, status, error) {
                console.log(xhr);
                console.log(status);
                console.log(error);
            },
            success: function (data) {
                var data2 = JSON.parse(data);

                    $('#datasetErrors').removeClass('show');
                    $('#datasetErrors').addClass('hidden');
                    var datasetTable='';
                    
                    $('#getData').val(getDataJSON);

                    if (method==='ajax_getPrograms') {
                        
                        //assemble JSON of programs returned for data download
                        var programArray=[];
//                        console.log(data2);
                        if (data2.data && Object.keys(data2.data).length !== 0) {
                            $.each(data2.data, function (i, d) {
                                programArray.push(d['pkProgramID']);
                            });                       
                        }
                        //console.log(programArray);
                        var projectIDsJSON = JSON.stringify(programArray);
                        $('#projectIDs').val(projectIDsJSON);
                        
                        if (data2.resultCount<limit){
                            $("#program_next_btn").hide();
                        }
                        else {
                            $("#program_next_btn").show();                            
                        }
                        datasetTable = createProgramTable(data2.data);
                        $("#programCount").html('<strong>Your search returned '+data2.resultCount+' program(s) with tree data in our inventory.</strong>');
                        $("#programTable tbody").fadeOut(100, function () {
                            $(this).empty().html(datasetTable).fadeIn(); //Empty content and repopulate
                    });
                }
                if (method==='ajax_getPlots') {                      
                        //console.log(data2);
                        //console.log(programIDs);
                        var programIDs=data2.programIDs;
                        var projectIDsJSON = JSON.stringify(programIDs);
                        $('#projectIDs').val(projectIDsJSON);                        
                        if (data2.resultCount<=limit){
                            $("#plot_next_btn").hide();
                        }
                        else {
                            $("#plot_next_btn").show();                            
                        }
                        datasetTable = createPlotTable(data2.data, data2.fuzzflag);
                        //console.log(data2.fuzzflag);
                        $("#plotCount").html('<strong>Your search returned '+data2.resultCount+' plot observations in our inventory.</strong>');
                        $("#plotTable tbody").fadeOut(100, function () {
                            $(this).empty().html(datasetTable).fadeIn(); //Empty content and repopulate
                    });
                }
                if (method==='ajax_getTrees') {
                        //assemble JSON of programs returned for data download
                        //console.log(data2);
                        var projectIDsJSON = JSON.stringify(data2.programIDs);
                        $('#projectIDs').val(projectIDsJSON);
                       // console.log($('#projectIDs').val());
                        if (data2.resultCount<=limit){
                            $("#tree_next_btn").hide();
                        }
                        else {
                            $("#tree_next_btn").show();                            
                        }                    
                        datasetTable = createTreeTable(data2.data, data2.fuzzflag);
                        $("#treeCount").html('<strong>Your search returned '+data2.resultCount+' tree observations in our inventory.</strong>');
                        $("#treeTable tbody").fadeOut(100, function () {
                            $(this).empty().html(datasetTable).fadeIn(); //Empty content and repopulate
                    });
                }
                $("#download-tab-nav").prop("disabled",false);
                
                //check if we are on the download tab and update downloads if needed
                //console.log ("active tab: "+$('#tableTab .active').attr('id'));
                if ($('#tableTab .active').attr('id')=="download-tab-nav"){
                        var programID = $('#projectIDs').val();
                        var posturl = baseURL + "data/ajax_getProgramFiles";
                        var formData = new FormData();   
                        formData.append('programID',programID);
                      $.ajax({
                                url: posturl,
                                cache: false,
                                data: formData,
                                method: 'POST',
                                contentType: false,
                                processData: false,
                                type: 'POST',
                                error: function (xhr, status, error) {
                                    console.log(xhr);
                                    console.log(status);
                                    console.log(error);
                                },
                                success: function (data) {
                                    var data2 = JSON.parse(data);
                                //    var data2=data;
                                //   console.log(data2);
                                   var file_download_div='';
                                   file_download_div = populateFileDownloadDiv(data2);             
                                   $("#fileDownloadDiv").html(file_download_div);
                                   setSelectedFiles();
                                    }
                                });    
                }
                //set hidden field to indicate if any of the programs returned are fuzzed
                var fuzzed=false;
                programArray = $('#projectIDs').val();
                var ajaxurl2 = baseURL + "data/ajax_arefuzzed";
                $.ajax({
                      method: "POST",
                      url: ajaxurl2,
                      data: {data : programArray}
                    })
                      .done(function(data) {
                          var data2 = JSON.parse(data);
                        $('#fuzzPlots').val(data2.fuzzed);
                      });

            }
        });
}


from Ajax beforeSend sometimes doesn't fire to show bootstrap progress bar

download from URL Kubeflow pipeline

I have been trying to create a kubeflow pipeline in my local machine and created a simple one component pipeline to download data from a given url.

import kfp
import kfp.components as comp

downloader_op = kfp.components.load_component_from_url(path)

def my_pipeline(url):
  downloader_task = downloader_op(url = url)

This works fine if I execute this pipeline through python code

client = kfp.Client() 

client.create_run_from_pipeline_func(my_pipeline,arguments=
     {
        'url': 'https://storage.googleapis.com/ml-pipeline-playground/iris-csv-files.tar.gz'
     })

But It shows an error when I try to execute the same code through Kubeflow UI. First I execute the above code which create a yaml file using below line and then upload the yaml file in kubeflow UI to create a new run. kfp.compiler.Compiler().compile(pipeline_func=my_pipeline,package_path='pipeline.yaml')

It give below error

This step is in Error state with this message: Error (exit code 1): cannot enter chroot for container named "main": no PID known - maybe short running container

I am not able to understand why it creates problems through UI and what is the solution.



from download from URL Kubeflow pipeline

How to uninstall jupyter

I have been trying to uninstall jupyter

I have tried the following commands

pip uninstall jupyter
pip3 uninstall jupyter

and

rm -rf /Users/$user/Library/Jupyter/*

Even after running all these commands when I type jupyter in the terminal I get the following message

usage: jupyter [-h] [--version] [--config-dir] [--data-dir] [--runtime-dir]
               [--paths] [--json]
               [subcommand]
jupyter: error: one of the arguments --version subcommand --config-dir --data-dir --runtime-dir --paths is required

What exactly is going wrong and why am I still able to use the command?



from How to uninstall jupyter

Apply func on dataframe columns that require values from previous rows and previous column

I need to apply a function on several rows of my table. The tricky part is that this function will use values of the previous row and also the value of the previous column.

In this example, the three columns that start with 'perf' are the ones that need to be updated with calcPerf function. So col "perf 60-40" will use the On/Off value in col "60-40" and "perf 30-30" the will use those of "30-30".

In reality I have 3000 columns to be updated instead of 3 in this example, so the idea would be to apply the function on the different columns dynamically.

The very first row should remain 0 by default as calcPerf function would not work on the first row.

For a better understanding I have two highlighted examples (blue and green). This shows what cells are used by the calcPerf function when on a specific cell.


import pandas as pd
df = {
    'open': ['4001','4010','4043','3924','4000'],
    'close': ['4002','4030','3901','3970','4009'],
    '50-20': ['On','On','On','On','On'],
    'perf 50-20':[0,0,0,0,0],
    '60-40': ['Off','Off','On','On','On'],
    'perf 60-40':[0,0,0,0,0],
    '30-30': ['On','Off','On','On','Off'],
    'perf 30-30':[0,0,0,0,0]
}
df = pd.DataFrame(df)
df

def calcPerf(currClose, prevClose, currOnOff,prevOnOff, lastCloseWhenOn, prevPerf, currOpen):
    if(currOnOff == "On" and prevOnOff =='On'):
        return ((currClose/prevClose)-1)*100
    if(currOnOff == "On" and prevOnOff =='Off'):
        return (( currOpen / lastCloseWhenOn )-1)*100
    if(currOnOff == "Off" and prevOnOff =='On'):
        return (( currOpen / prevClose )-1)*100
    if(currOnOff == "Off" and prevOnOff =='Off'):
        return 0

Below is the expected output along with the two examples mentioned above (blue and green)

enter image description here



from Apply func on dataframe columns that require values from previous rows and previous column

Cross Tab communication between iframe and different tab in Safari?

There are multiple questions about Cross-Tab and Cross-Domain communication but I'm asking specifically about Safari. That browser since version 7 added blocking of 3rd party tracking to iframes. So localStorage event and BroadcastChannel don't work on that browser when using inside an iframe.

My question is: are there any other solutions to cross-domain communication (between iframe and page with the same origin in a different tab) for Safari?

In my library sysend.js I've added a disclaimer that the cross-domain (same with any other library) doesn't work on Safari 7+. But maybe there is some trick to making that communication work.



from Cross Tab communication between iframe and different tab in Safari?

Connect React to Flask project

I first came across a project in which the backend is written in Python (framework flask), and I wrote the frontend in React. It's time to connect a little functionality between these two parts.

The essence of the project is that the user uploads a file, sees its display (name), can click the convert button and receive a file in a different format. The frontend part is written and the backend part is there, I need to connect these two parts, so that by clicking on the convert button (this is the React part), the Python code will run.

I have been reading and watching the best practices for the second day, but I have not succeeded in anything, I hope you can help me.

So, in order.

The SelectFileButton component is responsible for building a button for selecting a file

  export default function SelectFileButton(props) {
    const {setFileName} = props;
    const [file, setFile] = useState(null);

    const fileInput = useRef();
    const selectFile = () => {
        fileInput.current.click();
    };

    const updateName = () => {
        setFile(fileInput.current.files[0]);
        setFileName(fileInput.current.files[0]?.name);
    }
    
    return (
        <div>
            <input  type="file" 
                    style= 
                    ref={fileInput} 
                    onChange={(event)=> { updateName(event)  }} 
                    onClick={(event)=> { event.target.value = null}}/>
            
            <Button variant="contained" 
                    color="primary"  
                    onClick={selectFile} 
                    sx={styles.DispositionBottom} 
                    style=>
             <span>Upload</span>
            </Button> 
        </div>
    );
}

Next, the SelectFileButton is passed to the parent DisplaySelectedFile component. DisplaySelectedFile is responsible for displaying a button for selecting a file (SelectFileButton), displaying the file itself, a button for starting the conversion, and a few more elements that are not of interest to us

 export default function DisplaySelectedFile() {
    const [fileName, setFileName] = useState(null);
    const [showCard, setShowCard] = useState(false);

    const handleSelectFile = useCallback(
      (file) => {
        setFileName(file);
        file && setShowCard(true);
      },
      [setFileName, setShowCard]
    );
  
    return (
      <div>
        <SelectFileButton setFileName={handleSelectFile} />
        
        <div>
            {showCard && (
              <TableHead sx={styles.CommonStyle}>
                <TableRow >
                  
                    <TableCell sx={styles.CellStyleFileName}>
                      {fileName}
                    </TableCell>
      
                    <TableCell sx={styles.CellStyleButtonAndCross}>
                      <ConvertFileButton></ConvertFileButton>
                    </TableCell>

                </TableRow>
              </TableHead>
            )}
        </div>
      </div>
    );
  }

And the button itself, which should be responsible for converting the file

 export default function ConvertFileButton () {
    return (
        <Button>CONVERT</Button>
    )
}

Next, the most difficult question for me is to connect this button to a function (written in Python using a flask) that converts the file

    @mod.route('/transcript', methods=['POST'])
def create_transcript_task():
    if request.method == 'POST':
        if 'file' not in request.files:
            return "Something went wrong !"

        user_file = request.files['file']
        if user_file.filename == '':
            return "file name not found ..."

        else:
            path = os.path.join(os.getcwd(), 'static', user_file.filename)
            user_file.save(path)

            save_path = os.path.join(os.getcwd(), 'static')

            job = queue.enqueue(run_pipeline, path, save_path, job_timeout=-1, result_ttl=-1)
            job.meta['file_name'] = user_file.filename
            task_id = job.get_id()

        print('Run job ', get_job_from_id(queue, task_id))
        return redirect(url_for('backend.status_page') + f'?id={task_id}')

Function that reflects the download status

    @mod.route('/status', methods=['GET'])
def status_page():
    try:
        task_id = request.args.get('id', None)
        rq_job = rq.job.Job.fetch(task_id, connection=queue.connection)
        progress = rq_job.meta.get('progress', None)
        context = {}
        if progress is None:
            context['not_started'] = True
        elif progress < 100:
            context['progress'] = int(progress)
        else:
            context['get_link'] = url_for('backend.get_result') + f'?id={task_id}'

        return render_template('status.html', **context)
    except Exception as e:
        return render_template('error_page.html', error=str(e))

Yes, the question turned out to be very big. If I explained something wrong, then ask me questions. I hope you help me



from Connect React to Flask project

Thursday 25 August 2022

How can I style :visited elements that use React's onClick="" instead of href=""?

  • The website has a table.
  • In the table, I get data from the Firestore (and display this data to the user). Some cells in the table may link to other pages on the site (which are also implemented as a table).

Since there is a lot of information, the user can get confused which links they followed and which they have not touched; thus, I would like to mark with a different color when hovering over those links that the user has already visited.

By default, my link color is black, and if you hover over the link, it lights up blue. I would like the links visited by the user to be highlighted in a different color.

Below is an example of how I write the route

export default function DeviceCell({ device }) {
    const router = useNavigate()

    return (
        <TableRow>
          
            <TableCell>
                <a className="page-links" onClick={() => router(device.id)}>List of users</a>
            </TableCell>
        </TableRow>
    );
}

Also my .css file

.page-links {
    color: #3A3A3F;
    text-decoration: none;
    border-bottom: 1px black solid;
    border-bottom-width: 2px;
    cursor: pointer;   
}
    
.page-links:hover {
   color: #485FED;
   border-bottom: 1px #485FED solid;
   border-bottom-width: 2px;
}


from How can I style :visited elements that use React's onClick="" instead of href=""?

pass a variable between multiple custom permission classes in drf

I have a base permission class that two ViewSets are sharing and one other permission class each that is custom to each of the ViewSets, so 3 permissions all together, is there a way to pass a specific variable down from the base permission class to the other permission classes? My setup looks like this:

class BasePerm(permissions.BasePermission):
    def has_permission(self, request, view):
        some_var = # call an API using request variable

class Perm1(permissions.BasePermission):
    def has_permission(self, request, view):
        # get the value of some_var from BasePerm


class Perm2(permissions.BasePermission):
    def has_permission(self, request, view):
        # get the value of some_var from BasePerm


class MyViewSet1(mixins.CreateModelMixin, viewsets.GenericViewSet):
    permission_classes = [BasePerm, Perm1]


class MyViewSet2(mixins.CreateModelMixin, viewsets.GenericViewSet):
    permission_classes = [BasePerm, Perm2]


from pass a variable between multiple custom permission classes in drf

How do I catch AWS Amplify errors?

If you consider the following code

  React.useEffect(() => {
    Auth.currentUserInfo()
      .then((data) => {
        if (data.username) {
          //do something with data
        }
      })
      .catch((error) => console.log('No logged in user'))
  }, [])

When I look in my console, I see all this with my console log mixed in.

[ERROR] 14:14.682 AuthClass - No current user
at node_modules/@aws-amplify/core/lib-esm/Logger/ConsoleLogger.js:115:9 in prototype._log
at node_modules/@aws-amplify/core/lib-esm/Logger/ConsoleLogger.js:192:18 in <anonymous>
at node_modules/@aws-amplify/auth/lib-esm/Auth.js:2097:38 in user.confirmPassword$argument_2.onFailure

No logged in user
Error: ENOENT: no such file or directory, open '/Users/XXXXX/react-native-discord/http:/192.168.50.85:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&strict=false&minify=false'
    at Object.openSync (node:fs:585:3)
    at Object.readFileSync (node:fs:453:35)
    at getCodeFrame (/Users/XXXXX/react-native-discord/node_modules/metro/src/Server.js:949:18)
    at Server._symbolicate (/Users/XXXXX/react-native-discord/node_modules/metro/src/Server.js:1022:22)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Server._processRequest (/Users/XXXXX/react-native-discord/node_modules/metro/src/Server.js:429:7) {
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path: '/Users/XXXXX/react-native-discord/http:/192.168.50.85:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&strict=false&minify=false'
}
Error: ENOENT: no such file or directory, open '/Users/XXXXX/react-native-discord/http:/192.168.50.85:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&strict=false&minify=false'
    at Object.openSync (node:fs:585:3)
    at Object.readFileSync (node:fs:453:35)
    at getCodeFrame (/Users/XXXXX/react-native-discord/node_modules/metro/src/Server.js:949:18)
    at Server._symbolicate (/Users/XXXXX/react-native-discord/node_modules/metro/src/Server.js:1022:22)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Server._processRequest (/Users/XXXXX/react-native-discord/node_modules/metro/src/Server.js:429:7) {
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path: '/Users/XXXXX/react-native-discord/http:/192.168.50.85:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&strict=false&minify=false'
}

And I get this on my device enter image description here

Neither the try/catch or catch() seem to catch the error. How can I handle the error better without it blowing up in my console and device?



from How do I catch AWS Amplify errors?