Yet Another Openbox Pipe-Menu Generator

If you ever used the openbox-menu command and it doesn’t work, chreli-ob-menu is a reasonable alternative (I could have a biased opinion on that though). It is yet another simple perl script (perl is your friend, embrace it) that programmatically reads .desktop files in /usr/share/applications and ~/.local/share/applications and generates <openbox_pipe_menu> entries when called from ~/.config/openbox/menu.xml. It is also cognizant of new applications that are installed.

Installation

Download chreli-ob-menu_1.0.20160923.deb and execute the following:

Disclaimer: This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

sudo /usr/bin/dpkg -i chreli-ob-menu_1.0.20160923.deb

Usage

chreli-ob-menu [options]

Options:
    -a|--all                        generate pipe-menu for all categories
    -c|--category <category>        category to generate pipe-menu for
    -l|--list                       lists categories

    -h|--help                       display this help message
    -v|--version                    display version

Listing Supported Categories

chreli-ob-menu -l
Valid Categories:
 o Accessories
 o Development
 o Emulator
 o Game
 o Graphics
 o Internet
 o Multimedia
 o Office
 o Other
 o Preferences
 o System

Example Usage: Specific Category

<menu execute="/usr/bin/chreli-ob-menu -c System" id="openbox-System" label="System" icon="" />

The above will create a sub-menu called System with those applications using the category of System. If openbox has been compiled to show icons with menus, you can include the icon parameter that points to the image you would like to use.

Example Usage: All Categories

If you want to take the lazy approach and just have all the categories generate, you can do so by adding the following to ~/.config/openbox/menu.xml:

<menu execute="/usr/bin/chreli-ob-menu -a" id="desktop-all-menu" label="Menu" icon=""/>

Again, if openbox was compiled to include an icon with the menu items, you can give the icon parameter a value.

If you want just a static menu, you can call /usr/bin/chreli-ob-menu from the command line and copy-n-paste the output into ~/.config/openbox/menu.xml. You will, however, lose the dynamic capability when new applications are installed.

The chreli-ob-menu utility will do its level best to display icons to menu entries, including sub-menus, based on the gtk-icon-theme-name setting in ~/.gtkrc-2.0.

And that’s all I have to say about that.

Yet Another Simple Update Notifier

If you’re using a debian-based distro (such as Ubuntu or Linux Mint; both of which I view as Linux for Apple for Microsoft GUI babies either too lazy or afraid to use a terminal) or some derivative of RedHat (such as Fedora or CentOS) you may or may not have a systray applet that lets you know package updates are available. Below is a simple script, for debian-based installations, that will do just that.

The utility, chreli-update-check, written in Perl, leverages aptitude and yad (yet another dialog).

The aptitude command is as follows:

/usr/bin/aptitude search "~U" | /usr/bin/wc -l
3

The above instructs aptitude to search for upgradable packages (~U is shorthand) and is piped to the wc -l command to get the number of lines returned. You can read more about aptitude search terms here.

If you want to see what’s available to be updated, simply remove the | /usr/bin/wc -l from the above command:

/usr/bin/aptitude search "~U" 
i A libmenu-cache-bin    - LXDE implementation of the freedesktop Menu's cache (libexec)              
i A libmenu-cache3       - LXDE implementation of the freedesktop Menu's cache                        
i   pcmanfm              - extremely fast and lightweight file manager

If chreli-update-check detects updates (greater than 0 [zero]), it will construct the yad command to either display an in-your-face dialog: or a more subtle systray icon (displays details when moused over): The determination of either behavior is controlled by the chreli-update-check.nofification setting in ~/.config/chreli-update-check/chreli-update-check.conf; default is dialog.

To install chreli-update-check simply download chreli-update-check_1.0.20170520.deb and execute the following:

Disclaimer: This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

sudo /usr/bin/dpkg -i chreli-update-check_1.0.20170520.deb

Once installed, simply execute:

/usr/bin/chreli-update-check

To schedule its execution, add the following to your crontab:

15 */4 * * * DISPLAY=:0 /usr/bin/chreli-update-check > /dev/null 2>&1

The above will execute 15 minutes past, every 4 hours; you can adjust as you deem necessary.

The initial time chreli-update-check executes, it will create a chreli-update-check.conf in ~/.config/chreli-update-check with default settings for which icon to use (chreli-update-check.icon) and what type of notification (chreli-update-check.nofification):

# chreli-update-check 1.0.20170520
#
# configuration file for chreli-update-check

# icon to use for dialog or systray
# default: /usr/share/icons/Adwaita/16x16/apps/system-software-update.png
chreli-update-check.icon=/usr/share/icons/Adwaita/16x16/apps/system-software-update.png

# type of notification
# legal values:
#  o systray: displays icon in systray
#  o dialog : displays dialog
# default: dialog
chreli-update-check.nofification=systray

Adjust to your needs.

And that’s all I have to say about that.

Website Weather Integration

Here’s a quick tutorial on how to integrate your own, near real-time weather stats into your website. There are sites, such as AccuWeather (who should, in all honesty, change their name) and Weather Underground, that will do this for you, but I find that you’re 1) beholden to their style and 2) not very accurate. The Weather Underground one for example will say one thing on your site but when you click the sticker (that’s what they call it) it says a completely different thing; their mobile app does the same thing. As with any of these sites that provide weather information, unless you live right next to where they have their sensors set up (typically the closest airport), the readings are likely to be off. This tutorial will be using NOAA, so let’s get started.

What you’ll need first is your location, latitude and longitude. There are a number of sites that you can get that information from; this one works.

Next, you’ll need to download weather.js (right-click save-as) and change the lat & lon variables to your location.

/**
 * Change to your location. The below is Washington D.C.
 */
var lat = '38.907192';
var lon = '-77.036871';

Then add the following to the page you want to integrate weather into by adding a DIV element with the id of weather, like so:

<div id="weather"></div>

Towards the end of your page, before the <body> tag, add the following:

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="weather.js"></script>
<script>
    <!--
    $(document).ready(function() {
        // get initial weather
        getWeather();
        // refresh every 15 minutes; 900 * 1000
        setInterval(function() { getWeather(); }, 900000);
    }
    -->
</script>

The above will result in something like the below that will automatically update every 15 minutes.

The following CSS was used to style the current conditions icon:

#weather-icon {
    -webkit-border-top-left-radius:5px;
    -moz-border-radius-topleft:5px;
    border-top-left-radius:5px;
    -webkit-border-top-right-radius:5px;
    -moz-border-radius-topright:5px;
    border-top-right-radius:5px;
    -webkit-border-bottom-right-radius:5px;
    -moz-border-radius-bottomright:5px;
    border-bottom-right-radius:5px;
    -webkit-border-bottom-left-radius:5px;
    -moz-border-radius-bottomleft:5px;
    border-bottom-left-radius:5px;
    border: 1px solid #b0b0b0;
}

And that’s all I have to say about that.

Search WordPress Site Externally

Here’s a quick tutorial on how to perform searches against your WordPress site from another site.

To begin, add the following somewhere on your site’s page (borrowed from WordPress site):

<div id="search">
    <form role="search" method="post" id="searchform" class="searchform" action="<BLOG_SITE_URL>" onsubmit="this.target='search_results'">
        <div>
            <input type="text" value="" name="s" id="s" autocomplete="off">
            <input type="submit" id="searchsubmit" value="Search">
        </div>
    </form>
</div>
<p style="padding-bottom: 50px;"><p>

Where <BLOG_SITE_URL> is the URL to your WordPress site.

The onsubmit call opens the results in a new window (or tab depending on browser) named search_results. You could use _blank, but that would result in a new window every time, using a specific name uses the same window.

End result from above:

Example use:

And that’s all I have to say about that.

Listing WordPress Posts

So you have a WordPress site that hosts your blog posts along with a regular site and you want to list the blog posts on the other site, dynamically without having to manually add to the list every time you post something new. Here’s how I accomplished it.

Disclaimer: I found some of this on another site, but forgot where, so apologies for not giving credit where credit is due.

Create a posts.php page at the root of your WordPress site with the following:

<?php require('wp-blog-header.php');
    status_header(200);
    nocache_headers();
?>
<h4>::~ChrEli-BLOG~:: Posts</h4>
<table>
    <thead>
        <tr>
            <th>Post</th>
            <th>Published</th>
        </tr>
    </thead>
    <tbody>
<?php
$args = array( 'numberposts' => 100, 'category' => 0, 'post_status'=>"publish",'post_type'=>"post",'orderby'=>"post_date");
$posts = get_posts( $args );

 foreach ($posts as $post) :  setup_postdata($post); ?>
    <tr>
        <td><a href="<?php the_permalink(); ?>" title="<?php the_title();?>" target="_blank"> <?php the_title(); ?></a></td>
        <td><?php the_date(); ?></td>
    </tr>
<?php endforeach; ?>
    </tbody>
</table>

The above will produce an un-stylized output like the following:

To integrate with your other website, perform the following:

In the <head> element, add the following:

<script>
    <!--
    $(document).ready(function(){
        $( "#posts" ).load( "<LINK_TO_POSTS_PHP>", function(response, status, xhr){
            if (status == "error") {
                alert(msg + xhr.status + " " + xhr.statusText);
            }
         });
    });
    -->
</script>

Where <LINK_TO_POSTS_PHP> is the fully qualified link to the posts.php you created earlier.

Next, create a <div> element with the id of “posts”.

<div id="posts"><div>

If your sites are in different domains, you may get a message similar to the following in the JavaScript console:

XMLHttpRequest cannot load http://<BLOG_SITE_DOMAIN>/posts.php. No 
'Access-Control-Allow-Origin' header is present on the requested 
resource. Origin 'http://<SITE_ON_DIFFERENT_DOMAIN>' is therefore not allowed access.

Where <BLOG_SITE_DOMAIN> is the site for your WordPress blog and <SITE_ON_DIFFERENT_DOMAIN> is the site you trying to call http://<BLOG_SITE_DOMAIN>/posts.php from.

The reason for this is it is seen a a XSS (cross-site-scripting) attack. To work-around the above, add the following to the beginning of posts.php:

<?php header('Access-Control-Allow-Origin: http://<SITE_ON_DIFFERENT_DOMAIN>'); ?>

Whatever you do, DO NOT put * where http://<SITE_ON_DIFFERENT_DOMAIN> is.; that’s just asking for trouble.

The end result should look as follows:

And that’s all I have to say about that.