Author: Joel G Mathew

Joel G Mathew, known in tech circles by the pseudonym Droidzone, is an Android and Linux enthusiast. His favorite pastime is grappling with GNU compilers, discovering newer Linux secrets, writing scripts, hacking roms, and programs (nothing illegal), reading, blogging. and testing out the latest gadgets. When away from the tech world, Joel is a practising ENT Surgeon.

You have something known as DATABASE_URL, which has to be used in the backup command. To find your database url, run the following command:

heroku pg
=== HEROKU_POSTGRESQL_JUPITER_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           1/20
PG Version:            10.15
Created:               2018-12-16 08:57 UTC
Data Size:             12.9 MB
Tables:                39
Rows:                  4751/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-tapered-53472

Now run the command to create the backup:

$ heroku pg:backups:capture HEROKU_POSTGRESQL_JUPITER_URL
Starting backup of postgresql-copred-72... done

Use Ctrl-C at any time to stop monitoring progress; the backup will continue running.
Use heroku pg:backups:info to check progress.
Stop a running backup with heroku pg:backups:cancel.

Backing up JUPITER to b007... done

Now, download the backup to local folder:

$ heroku pg:backups:download
Getting backup from ⬢ mysterious-boco-302564... done, #7
Downloading latest.dump... ████████████████████████▏  100% 00:00 291.55KB 

The backup has been created in the current directory with the name latest.dump.

Reference: Heroku doku

To restore a backup, use the restore command:

$ heroku pg:backups:restore b101 DATABASE_URL --app sushi

This will restore backup id b101 to the specified database URL in the app sushi. Note: you can omit the backup id and the target database to restore the latest backup to DATABASE_URL, otherwise both backup id and target database must be provided.

My system python3 version is 3.6. I need to install python3.9 in a directory, and run it.

First we need to add the deadsnakes repo for new python versions. Otherwise Ubuntu cannot get newer versions.

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.9 python3.9-venv python3.9-dev
sudo apt install python3-venv
python3.9 -m venv venv

Now, we have created a virtualenv folder named venv.

Activate it:

. venv/bin/activate

For django, you will need to install all the requirements again.

Scenario: I have Flutter as front end, and django as back end. django-rest-framework is used for managing the API. I have a dataset of customer profile details, which needs to be edited. So from the flutter front end, this data is passed to the backend, which updates the data, and sends a successful message.

My model:

class customer(models.Model):
    # Need autoincrement, unique and primary
    cstid = models.AutoField(primary_key=True, unique=True)
    date_of_registration = models.DateField(default=timezone.now)
    insurance_number = models.CharField(max_length=100, blank=True, null=True)
    name = models.CharField(max_length=35, blank=False)
    ageyrs = models.IntegerField(blank=True)
    agemnths = models.IntegerField(blank=True)
    dob = models.DateField(null=True, blank=True)

I write an APIView, as described in the documentation:

class UpdateCustomerDetail(APIView):
    """
    Retrieve, update or delete a snippet instance.
    For details, refer: https://www.django-rest-framework.org/tutorial/3-class-based-views/
    """
    print("In UpdateCustomerDetail")

    def get_object(self, pk):
        try:
            return customer.objects.get(pk=pk)
        except customer.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = customerSerializer(snippet)
        return Response(serializer.data)

    def patch(self, request, pk, format=None):
        cst = self.get_object(pk)
        print("request.data:", request.data)
        customer_data = json.loads(request.data['customer'])
        serializer = customerSerializer(cst, data=customer_data)
        if serializer.is_valid():
            print("Serializer is valid")
            serializer.save()
            print(Response(serializer.data))
            return Response(serializer.data)
        else:
            print("Serializer is NOT valid")
            print(serializer.errors)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        snippet = self.get_object(pk)
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

Now, add a url for it:

    path('update_customer_new/<int:pk>/', views.UpdateCustomerDetail.as_view(),
         name='update_customer_new'),

So, what we are doing, is to pass the pk (which never changes), along with the JSON of a representation, of the model, here, customer, to django.

I am using it from Flutter., So I call the url: /api/update_customer_new/5/

The Flutter code is as follows:

  Future updateCustomerNew({
    int clinicID,
    Customer customer,
  }) async {
    print("In Network::updateCustomer");
    String basicAuth =
        'Basic ' + base64Encode(utf8.encode('$userName:$passWord'));
    print(basicAuth);
    int cstID = customer.cstid;
    var response = await http.patch(
      '${host}update_customer_new/${cstID}/',
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
        'authorization': basicAuth,
      },
      body: jsonEncode(<String, String>{
        'clinicID': clinicID.toString(),
        'customer': jsonEncode(customer),
      }),
    );
    print("Sending: ${jsonEncode(customer)}");
    print('Response status: ${response.statusCode}');
    print(response.body);
    return response.body;
  }

So, django gets the pk, as part of the url, and the data as json. It then calls the APIView, which passes the request to the patch method. The object is retrieved by its pk, so we can update any or all fields on it.

You may have come across the following error:

ERROR 1273 (HY000) at line 200: Unknown collation: ‘utf8mb4_0900_ai_ci’

To solve this:

sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' /home/joel/myappointments/appointmentsdj.sql

Now you can import the sql safely.

The following is not exclusive to Ubuntu. It probably works on any Linux.

As many of you know, I am an ENT surgeon by profession, and also a tech enthusiast. As part of my trade, I need to do endoscopy of the nose and throat, and also record and give reports to patients. For this, I use a cheap AV to USB recording device, called EasyCap. For Windows, it comes with a recording software, called Honestech. However. for Linux. one can simply use vlc for recording.

Install vlc:

sudo apt install vlc

For recording, the steps include:

Install vlc.
Open vlc
Open Network Stream:
Video device name: /dev/video2

In View

You may need to change and try the various available video devices. One of them will be your webcam, and the other, the AV to USB device.

If the color saturation bothers you, install v4l2ucp.

It is not normally available for Ubuntu 20+, but you can install it like below:

Download the deb from here

First install qt4:

sudo add-apt-repository ppa:rock-core/qt4
sudo apt-get update
sudo apt-get install libqtcore4
sudo dpkg -i ~/Downloads/v4l2ucp_2.0.2-4build1_amd64.deb
sudo apt-get install -f

You can experiment with color settings by loading v4l2ucp

Here’s an example:

    $('body').on('click', '#btnSavePendingPaymentInfo', function () {
        var SelectorID = $(this).attr('id');
        console.log(`Saving payment info`);
        csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
        console.log(`csrftoken: ${csrftoken}`);
        url = $("#UpdatePaymentModal").data('update-link');
        const request = new Request(
            url,
            { headers: { 'X-CSRFToken': csrftoken } }
        );
        var checkin_num = $('body').find("#CheckinNo").html();
        var HospitalID = $('body').find("#PatientIP").html();
        var amt_paid = $("#pending_amt_paid").val();



        // Build formData object.
        let formData = new FormData();
        formData.append('checkin_num', checkin_num);
        formData.append('HospitalID', HospitalID);
        formData.append('amt_paid', amt_paid);


        fetch(request, {
            method: 'POST',
            mode: 'same-origin',  // Do not send CSRF token to another domain.
            body: formData,
        }).then(function (response) {
            console.log(`Received server response.`);
            console.log(response);
            // text = response.statusText;
            response.text().then(
                text => $("#" + SelectorID).notify(text, { position: "right middle", className: 'success' })
            );

        });
    });

A snackbar is a convenient widget for displaying short messages about completed events.

To create a Snackbar, use the code:

Scaffold.of(context).showSnackBar(
      SnackBar(
        content: Text('$response'),
        backgroundColor: msgColor,
      ),
    );