<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Mekolle Sone Gillis Ekeh Junior on Medium]]></title>
        <description><![CDATA[Stories by Mekolle Sone Gillis Ekeh Junior on Medium]]></description>
        <link>https://medium.com/@sone_gillis?source=rss-7f3f04040a85------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*FOyIMYTZ5M4EbgD-qmuxgA.jpeg</url>
            <title>Stories by Mekolle Sone Gillis Ekeh Junior on Medium</title>
            <link>https://medium.com/@sone_gillis?source=rss-7f3f04040a85------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 24 May 2026 02:12:15 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@sone_gillis/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Generic Multi-Field Django Model Custom Validation]]></title>
            <link>https://medium.com/django-unleashed/generic-multi-field-django-model-custom-validation-925d2c9c7f2c?source=rss-7f3f04040a85------2</link>
            <guid isPermaLink="false">https://medium.com/p/925d2c9c7f2c</guid>
            <category><![CDATA[django-models]]></category>
            <category><![CDATA[django]]></category>
            <dc:creator><![CDATA[Mekolle Sone Gillis Ekeh Junior]]></dc:creator>
            <pubDate>Mon, 01 Jan 2024 22:52:17 GMT</pubDate>
            <atom:updated>2024-04-19T18:42:48.195Z</atom:updated>
            <content:encoded><![CDATA[<p>Exciting news! Starting April 19, 2024, this story will no longer be updated on Medium. Don’t worry though, I just started a blog where you can access updates to this story <a href="https://blog.gillis.live/generic-multi-field-django-model-custom-validation/">here</a>.</p><p>In this article, you will learn how you can create a generic multi-field model custom validation mechanism for your django projects. By default, django provides a way for you to validate your model fields by passing a list of validator functions to the validators argument. What if we have to apply validations to multiple model fields? For example, in an e-commerce application, say we have to ensure that when a user selects a discount of type percentage, then the discount value should be less than or equal to 100. We will in the following sections, with detailed code and explanations, see how we can do this in Django.</p><h3>Creating the model</h3><p>Let’s assume we are implementing a <strong>Coupon </strong>model that keeps track of coupons we offer to customers. Our coupon model looks like this</p><pre>class Coupon(models.Model):<br>    class DiscountTypes(models.TextChoices):<br>        PERCENTAGE_DISCOUNT = &quot;percentage_discount&quot;<br>        FIXED_CART_DISCOUNT = &quot;fixed_cart_discount&quot;<br>        FIXED_PRODUCT_DISCOUNT = &quot;fixed_product_discount&quot;<br>        BOGO = &quot;bogo&quot;, _(&quot;BOGO (Buy X GET X/Y) Offer&quot;)<br><br>    class DisplayIn(models.TextChoices):<br>        MY_ACCOUNT = &quot;my_account&quot;<br>        CHECKOUT = &quot;checkout&quot;<br>        CART = &quot;cart&quot;<br><br>    code = models.CharField(max_length=20, unique=True, null=True)<br>    amount = models.FloatField(default=0)<br>    start_date = models.DateTimeField(auto_now=True)<br>    expiry_date = models.DateTimeField()<br>    free_shipping = models.BooleanField(default=False)<br>    description = models.TextField(max_length=200)<br>    discount_type = models.CharField(max_length=40, choices=DiscountTypes.choices)<br>    apply_automatically = models.BooleanField(default=False)<br>    display_in = MultiSelectField(max_length=20, max_choices=3, choices=DisplayIn.choices, null=True)<br>    minimum_spend = models.IntegerField(default=0, null=True)<br>    maximum_spend = models.IntegerField(default=0, null=True)<br>    individual_use_only = models.BooleanField(default=False)<br>    exclude_sale_items = models.BooleanField(default=False)<br>    email_restrictions = models.TextField(help_text=<br>                                          &quot;Comma separated list of emails to restrict for access to this coupon&quot;,<br>                                          null=True, blank=True)<br>    def __str__(self):<br>        return self.code</pre><p>The coupon has different discount types including:</p><ul><li>Percentage discount</li><li>Fixed cart discount</li><li>fixed product discount</li><li>Bogo discount</li></ul><h3>Validation</h3><p>Let’s say we want to ensure that, if an admin creates a percentage discount coupon, the <strong>amount</strong> field should not be above <strong>100. </strong>To make this generic and reusable, let’s create a <strong>Validator</strong> abstract base class. This is will provide two methods:</p><p><strong>register — </strong>A class method that will be used to register the fields that we want to validate and the error message that should be shown.</p><p><strong>run — </strong>An abstract method that will be implemented by child classes to provide the actual validation functionality.</p><p>Our <strong>Validator </strong>abstract base class should look like this:</p><pre>from abc import ABC, abstractmethod<br>from django.db import models<br>import typing as t<br><br><br>class Validator(ABC):<br>    @classmethod<br>    def register(cls, fields: t.List[str] = [], message=&quot;Model is not valid&quot;):<br>        cls.fields = fields<br>        cls.message = message<br>        return cls()<br><br>    @abstractmethod<br>    def run(self, model: models.Model):<br>        pass</pre><p>Now let’s create a mixin called <strong>ModelValidationMixin. </strong>This will override the <strong>clean</strong> and the <strong>save</strong> methods of the django model. It will loop through a <strong>validators </strong>(a list of Validator implementations) property and check for validation errors. Our <strong>ModelValidationMixin</strong> should look like this:</p><pre>class ModelValidationMixin:<br>    validators: t.List[Validator] = []<br><br>    def clean(self):<br>        for validator in self.validators:<br>            if not validator.run(self):<br>                raise ValidationError(validator.message)<br><br>    def save(self, *args, **kwargs):<br>        self.full_clean()<br>        super(ModelValidationMixin, self).save(*args, **kwargs)</pre><p>Next, let’s implement a validation class (<strong>LessThan100IfPercentageDiscount</strong>) which will answer our initial question above — Ensure that if the discount type is <strong>percentage_discount, </strong>the discount amount inputted should not go above <strong>100</strong>.</p><pre>class LessThan100IfPercentageDiscount(Validator):<br>    def run(self, model):<br>        return not (model.discount_type == Coupon.DiscountTypes.PERCENTAGE_DISCOUNT and model.amount &gt; 100.0)</pre><p>As a bonus let’s also implement another validation class that will ensure that the <strong>start_date</strong> is never ahead of the <strong>expiry_date</strong> (<strong>LessThanValidator</strong>) — Usable for comparing other fields that need a less-than comparism.</p><pre>class LessThanValidator(Validator):<br>    def run(self, model: models.Model):<br>        return getattr(model, self.fields[0]) &lt; getattr(model, self.fields[1])</pre><h3>Let’s wrap it up</h3><p>To use the above validators, our Coupon model class will then look like:</p><pre>class Coupon(ModelValidationMixin, models.Model):<br>    class DiscountTypes(models.TextChoices):<br>        PERCENTAGE_DISCOUNT = &quot;percentage_discount&quot;<br>        FIXED_CART_DISCOUNT = &quot;fixed_cart_discount&quot;<br>        FIXED_PRODUCT_DISCOUNT = &quot;fixed_product_discount&quot;<br>        BOGO = &quot;bogo&quot;, _(&quot;BOGO (Buy X GET X/Y) Offer&quot;)<br><br>    class DisplayIn(models.TextChoices):<br>        MY_ACCOUNT = &quot;my_account&quot;<br>        CHECKOUT = &quot;checkout&quot;<br>        CART = &quot;cart&quot;<br><br>    code = models.CharField(max_length=20, unique=True, null=True)<br>    amount = models.FloatField(default=0)<br>    start_date = models.DateTimeField(auto_now=True)<br>    expiry_date = models.DateTimeField()<br>    free_shipping = models.BooleanField(default=False)<br>    description = models.TextField(max_length=200)<br>    discount_type = models.CharField(max_length=40, choices=DiscountTypes.choices)<br>    apply_automatically = models.BooleanField(default=False)<br>    display_in = MultiSelectField(max_length=20, max_choices=3, choices=DisplayIn.choices, null=True)<br>    minimum_spend = models.IntegerField(default=0, null=True)<br>    maximum_spend = models.IntegerField(default=0, null=True)<br>    individual_use_only = models.BooleanField(default=False)<br>    exclude_sale_items = models.BooleanField(default=False)<br>    email_restrictions = models.TextField(help_text=<br>                                          &quot;Comma separated list of emails to restrict for access to this coupon&quot;,<br>                                          null=True, blank=True)<br>    validators = [<br>        LessThanValidator.register([&quot;start_date&quot;, &quot;expiry_date&quot;],<br>                                   message={&quot;expiry_date&quot;: &quot;Should be greater than start date&quot;}),<br>        LessThan100IfPercentageDiscount.register(message={&quot;amount&quot;: &quot;Amount should be less that 100 if coupon type is&quot;<br>                                                                    &quot;percentage_discount&quot;})<br>    ]<br><br>    def __str__(self):<br>        return self.code</pre><p>After running this, in the django admin interface, you’ll notice an error that appears while trying to input a discount amount of 120 while the discount type is percentage_discount</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/967/1*Bp0QOkvMn1qzAf0uqgasFg.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=925d2c9c7f2c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/django-unleashed/generic-multi-field-django-model-custom-validation-925d2c9c7f2c">Generic Multi-Field Django Model Custom Validation</a> was originally published in <a href="https://medium.com/django-unleashed">Django Unleashed</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Detect when your android application is idle]]></title>
            <link>https://medium.com/@sone_gillis/detect-when-your-android-application-is-idle-5e055e6809c?source=rss-7f3f04040a85------2</link>
            <guid isPermaLink="false">https://medium.com/p/5e055e6809c</guid>
            <category><![CDATA[android-apps]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[androiddev]]></category>
            <dc:creator><![CDATA[Mekolle Sone Gillis Ekeh Junior]]></dc:creator>
            <pubDate>Thu, 02 Jan 2020 20:56:50 GMT</pubDate>
            <atom:updated>2024-05-14T10:40:14.853Z</atom:updated>
            <content:encoded><![CDATA[<p>Exciting news! Starting April 19, 2024, this story will no longer be updated on Medium. Don’t worry though, I just started a blog where you can access updates to this story <a href="https://codewithgillis.com/detect-when-your-android-application-is-idle/">here</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*pu9VPyHCJqnhqQ7dVQqSEw.png" /></figure><p>Sometime ago, while working on an android project, and I reached a point where I had to detect when my application is <strong>idle</strong> and perform a certain action. By idle here I mean the user has opened the app but is not interacting with.</p><p><strong>What are we going to build?<br></strong> Let’s assume a bank wanted to give it’s customers the ability to increase their account balances just by clicking a button 😃 (that might never happen, yes I know) and we need to build such an app for them. The user’s balance will reset to 0 if he delays for a period of time without interacting with the app. Simple app right? But remember our goal is to detect when the user has not been interacting with our app for sometime and not to build some fancy application. After this, you will be able to detect idle state of your application. Now enough of the talking. Let’s dive into some concepts and code.</p><p>We’ll start by creating a new android project on android studio. Feel free to call it whatever you want. I’ll provide a link to the repo at the end. Next we’ll create an empty activity and call it <strong>MainActivity. </strong>We’ll then create java class and call it <strong>BaseActivity</strong>. BaseActivity will be the parent class of all activities. The reason why I did this is because we’ll not want to write code in all our activities where we need to detect idle state of the application.</p><p>Let’s add some code to the BaseActivity class.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/564/1*xivdRtNMlFE58KLQImdlzw.png" /></figure><p>As you can see I created a method <strong>myCustomOnCreate</strong> that will be overidden by all child activities inorder to render the layout.</p><p>I already created the layout that allows the user add up what he has in account by simply tapping on a button. I have also implemented the java functionality. Remember that’s not purpose of this article so we’ll focus more performing an action when our app is idle. This is a look of our simple app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*H0AYTCVjS_ePGwFak_KU7A.jpeg" /></figure><p>We will be using the android <strong>Handler </strong>class and <strong>Runnable</strong> interface. Inside the BaseActivity class, let’s create a <strong><em>handler object</em></strong><em> </em>and pass a <strong><em>runnable object</em></strong><em> </em>with a <strong><em>timeout</em> </strong>to the handlers <strong><em>postDelayed. </em></strong>This will call the <strong><em>run</em></strong> method implementation inside our runnable implementation after timeout has occured. Let’s create a method and call it <strong><em>reactToIdleState. </em></strong>This method will be called inside the run method of the runnable implementation. We will also need to override this method inside all our Activities that extend BaseActivity. That is the method that will be called when the app becomes idle</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/318/1*7bjY26Tx7K6ie3w0oDBM0g.png" /></figure><p>In the BaseActivity onCreate method, we will initialize our handler and call it’s postDelayed method passing into it the runnable object and the timeout as shown below. This simply means “Call the runnable’s run method after a timeout has reached”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/427/1*sUHf94dtbkSR6q65dnUOtg.png" /></figure><p>There are only two ways the user can interact with our app. Either by simple touching the screen or clicking the button to add their balance. So will make our BaseActivity class implement the <strong>View.OnClickListener</strong> interface and implement it’s <strong><em>onClick</em></strong><em> </em>method. We will also the override the Activity <strong><em>onTouchEvent</em>. </strong>In these two methods we will remove the callback from the handler by calling the<strong> <em>removeCallbacks</em></strong> method and passing to it our runnable object, then call the postDelayed method again on the handler object. I have created a method called <strong><em>resetHandler</em></strong> to the job. We will call this method in our onClick and OnTouchEvent methods so every time user touches his screen or clicks the button we re-initialize the post delay.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/369/1*3GTLReSGBVNhUmSHdsqJRA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/376/1*KlPLxwA-0S7obM56mUFdlw.png" /></figure><p>If you notice, in the onClick method I called a <strong><em>myCustomOnClick</em></strong> method that will be overridden inside all activities that extend BaseActivity and needs to respond to click events. That’s it for the BaseActivity. Now any of our activities can extend our BaseActivity and override the appropriate methods to perform actions on app idleness.</p><p><strong>Our MainActivty will do the following</strong></p><ul><li>Declare member variables and initialise them in the <strong><em>myCustomOnCreate</em></strong> method.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/462/1*hi0wsx_kwD9rKU24w-Bweg.png" /></figure><ul><li>React to the click events by overriding the BaseActivity <strong><em>myCustomOnClick </em></strong>method.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/413/1*-LvuOY5jiJ3RYJeZ8lIEXQ.png" /></figure><ul><li>Override the BaseActivity <strong><em>reactToIdleState</em></strong> method and perform desired action when the app is idle.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/305/1*aYz4ZBWDgXy0veNjztuaDA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/419/1*SzAD17CR7KhrQ71mp9yDQg.png" /></figure><p>That’s it for our app. You can improve on the app functionality. But I would expect you to apply the concept to your own application where you need to know when the user hasn’t been interacting with the app for a while. Any idea about some other approach or questions will be highly welcome in the comment section. I’ll also be pleased if there could be corrections or something to add in the comment section. Here is the link to the complete project <a href="https://github.com/sonegillis/idle-state-detect-app">https://github.com/sonegillis/idle-state-detect-app</a>. You can clone the project and run on your android device. To know more about Handlers and Runnable you can check out the following links to the google android developer site.<br>- <a href="https://developer.android.com/reference/android/os/Handler">https://developer.android.com/reference/android/os/Handler</a><br>- <a href="https://developer.android.com/reference/java/lang/Runnable">https://developer.android.com/reference/java/lang/Runnable</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5e055e6809c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[JAVA SERVLETS]]></title>
            <link>https://medium.com/@sone_gillis/java-servlets-e225e323d998?source=rss-7f3f04040a85------2</link>
            <guid isPermaLink="false">https://medium.com/p/e225e323d998</guid>
            <category><![CDATA[spring-framework]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[servlet]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Mekolle Sone Gillis Ekeh Junior]]></dc:creator>
            <pubDate>Thu, 19 Sep 2019 09:14:05 GMT</pubDate>
            <atom:updated>2019-09-19T09:14:05.729Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Simple HTTP Client Server communication architecture" src="https://cdn-images-1.medium.com/max/494/1*D2GnNO-VKNc5-77-kp8Pfw.png" /></figure><h3>So what are servlets and what do they do?</h3><p>Servlets are a java technology used to handle incoming HTTP requests on a server. When an HTTP request is made to a server from browser for example, this request gets routed to <em>Web Application Container</em> simple called a <em>Web Container. </em>These web containers often contain one or more servlets. So when an http request is routed to a web container it in turn routes it to one of the servlets contained within it. The servlet then processes the HTTP request by looking at the headers and understanding how to interpret the body.</p><p>Simply, a servlet is nothing more than a Java object which contains several methods with the key methods being <em>doGet </em>and <em>doPost </em>methods each used for handling HTTP request with the GET and POST request method respectively. A java servlet is an implementation of the HttpServlet interface and implements several request handling methods that correspond to HTTP request methods.</p><h3>How does the Web Container knows which servlet to route a request to?</h3><p>Web containers usually use some routing function or simple a router to determine based on the incoming request, which servlet should do the handling. In Java these are configured in a file named <strong><em>web.xml. </em></strong>When a request comes from a client, the web container looks in the the web.xml file to get which servlet to use to handle the incoming request.</p><h3>Conclusion</h3><p>Servlets are the basic java objects used in handling incoming http request. Although creating Servlets by implementing the default HttpServlet java interface is the long way to go about building scalable Java web applications, understanding the fundamentals of how they work is very important as it is used by more advanced frameworks like <strong>Spring</strong> which has become a major tool in building scalable java web applications.</p><p>I will be posting some articles in the near future about the Spring framework and how we can use to build cloud services.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e225e323d998" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>