Execute Shell Commands from a Python GUI App

GUI Execute Commands

Here’s my Python – TKinter App that takes a set of Shell Commands from a .json file and displays them for individual execution when a button is clicked. Write these frequently used commands once and let the GUI program remember their syntax.

Keep 3 files in the same directory:

  • guiExecuteCommands.py The TKInter Program
  • config.json The Configuration Data
  • cmds.json The Initial Command Set

Contents

  • The TKInter Program File – guiExecuteCommands.py
  • The Configuration Data File – config.json
  • The Initial Command Set – cmds.json
  • A Screenshot of the TKInter Program
  • A run log of the program

The TKInter Program File – guiExecuteCommands.py

Here is the guiExecuteCommands.py file.

#!/usr/bin/python
# -*- coding: utf-8 -*-
# guiExecuteCommands.py
import sys, os, time, subprocess, json, atexit

# if not('.' in sys.path): sys.path.append('.')
# from MyCommands import cmds

import Tkinter, tkFileDialog

class Theapp(Tkinter.Tk):
    def __init__(self,parent):

        # joe's init
        with open('config.json') as data_file:
            cfg_data = json.load(data_file)
        self.cfg_data = cfg_data 

        with open(cfg_data[0]['commandsf']) as data_file:
            cmds = json.load(data_file)
        self.cmds = cmds 


        atexit.register(self.on_exit) # http://stackoverflow.com/a/28664350/601770


        # /joe's init




        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def on_exit(self):
        ''' http://stackoverflow.com/a/28664350/601770  
            save the state that has been changed
        '''

        self.cfg_data[0]['workingd'] = self.cwd.get()


        print "self.cwd.get(): %s"%(self.cwd.get())
        print "self.cfg_data: %s"%(self.cfg_data)

        with open('config.json', 'w') as f:
            json.dump(self.cfg_data, f)

    def execute_cmd(self, rnum):
        ''' C:\1d\PythonPjs\subprocessPjs\executeCommandsPj\executeCommands\executeCommands.py

        '''
        commandstring = self.cmd_entries[rnum].get()
        cwdpath = self.cwd.get()
        outstr = subprocess.check_call(commandstring, cwd=cwdpath, shell=True)  #  Convenience Function
        print outstr


    ## http://stackoverflow.com/a/16777523/601770   
    def bclick(self, rnum):
        def click():            
            self.execute_cmd(rnum)
        return click



    def browse2cwd(self):   
        """
        http://stackoverflow.com/questions/11295917/how-to-select-a-directory-and-store-the-location-using-tkinter-in-python
        http://tkinter.unpythonic.net/wiki/tkFileDialog
            find "def askdirectory(self):"
        """   
        tkFileDiaOpt4Dir = {}
        tkFileDiaOpt4Dir['initialdir'] = self.cwd.get()
        tkFileDiaOpt4Dir['mustexist'] = False
        tkFileDiaOpt4Dir['parent'] = self
        tkFileDiaOpt4Dir['title'] = 'Browse to set CWD.'

        self.cwd.set( tkFileDialog.askdirectory(**tkFileDiaOpt4Dir) )

        print "browse2cwd:  self.cwd.get(): %s"%(self.cwd.get())

    def initialize(self):
        self.cwd = Tkinter.StringVar()
        self.cwd.set(self.cfg_data[0]['workingd'])

        self.grid()  # make this be a grid

        ### add the gui elements in here

        ## browse to working directory
        label = Tkinter.Label(self, text="Working Directory", fg="white",bg="blue")
        label.grid(column=0,row=0,columnspan=3,sticky='W')

        self.cwd_entry = Tkinter.Entry(self, width=80, textvariable=self.cwd)
        self.cwd_entry.grid(column=0,row=1,columnspan=2, sticky='W') # http://effbot.org/tkinterbook/entry.htm

        b = Tkinter.Button(self,text=u"Browse", command=self.browse2cwd)
        b.grid(column=2,row=1) 

        toprowscount = 2


        ## command row elements len == len(MyCommands.cmds)
        self.buttons = []
        self.cmd_entries = []
        for rnum, cmd in enumerate(self.cmds):


            label = Tkinter.Label(self, anchor="w",text=cmd['label'], fg="white",bg="blue")
            label.grid(column=0,row=rnum+toprowscount,sticky='EW')

            self.cmd_entries.append( Tkinter.Entry(self, width=60) )
            self.cmd_entries[-1].grid(column=1,row=rnum+toprowscount,sticky='EW'); self.cmd_entries[-1].insert(0, (cmd['cmd']+' '+ cmd['args']))


            b = Tkinter.Button(self,text=u"Ex%s"%(rnum), command=self.bclick(rnum))
            b.grid(column=2,row=rnum+toprowscount) 

            self.buttons.append(b)


        ## Finish up
        self.grid_columnconfigure(0,weight=1) # make resizable
        self.resizable(True,False)            # make resizable ONLY HORIZONTALLY




if __name__ == "__main__":
    app = Theapp(None)
    app.title('Gui Execute Comands')
    app.mainloop()

The Configuration Data File – config.json

Here is the config.json file.

[{
   "programd": "C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand", 
   "commandsf": "C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand\\cmds.json",  
   "configd": "C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand", 
   "workingd": "C:/1d/CrossPlatformPjs/CordovaPjs/cordovaAngular00Pj/cordovaAngular00"
}]

The Initial Command Set – cmds.json

Here is the (INITIAL) cmds.json file

[
  {"cmd": "cordova", "args": "run android", "label": "android build 4 device"}, 
  {"cmd": "cordova", "args": "emulate android", "label": "android build 4 emulation"}, 
  {"cmd": "dir", "args": "*", "label": "dir of working dir"}
]  

A Screenshot of the TKInter Program

Here is a screenshot of the program.

guiExecuteShot

A run log of the program

Here is a run log.

Note: if the user changed the working directory, on exit the new working directory will be saved in the config.json file.

C:\1bat\guiExecuteCommands>guiExecuteCommands.py
browse2cwd:  self.cwd.get(): C:/1d/CrossPlatformPjs/Building Single Page Web Apps with AngularJS PJ
 Volume in drive C is Windows
 Volume Serial Number is F2FB-4810

 Directory of C:\1d\CrossPlatformPjs\Building Single Page Web Apps with AngularJS PJ

12/23/2015  09:58 AM    <DIR>          .
12/23/2015  09:58 AM    <DIR>          ..
12/23/2015  11:11 AM    <DIR>          zetc
               0 File(s)              0 bytes
               3 Dir(s)  900,352,217,088 bytes free
0
self.cwd.get(): C:/1d/CrossPlatformPjs/Building Single Page Web Apps with AngularJS PJ
self.cfg_data: [{u'programd': u'C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand', u'commandsf': u'C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand\\cmds.json', u'configd': u'C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand', u'workingd': u'C:/1d/CrossPlatformPjs/Building Single Page Web Apps with AngularJS PJ'}]

C:\1bat\guiExecuteCommands>

Download an App from Google Play to a PC & Install it on a Tablet (Sideload)

Download an App from Google Play to a PC & Install it on a Tablet

Download App to PC

ref How to Download Android Apps from Play Store to PC?

  1. Find the App URL on google play store for your account
  2. Here’s the App URL for Cogi – Notes & Voice Recorder
    https://play.google.com/store/apps/details?id=com.cogi.mobile
  3. Copy the id == com.cogi.mobile
    From the App URL
    To https://apps.evozi.com/apk-downloader/
  4. Click on newly appeared button
    “Generate Download Link”
Result:
  Package Name: com.cogi.mobile [Play Store]
  File Size: 12.1 MB
  QR Code: View
  MD5 File Hash: ee75eba0fef749dba8796c2eb5cab309
  Last Fetched: 2015-08-03 21:31:36
  Version: 1.17.2 (94)
  1. Click on the newly appeared button
    “Click here to download =com.cogi.mobile now”
  2. Put the download into yourPC PATH_TO_Apps/Cogi/
  3. Verify the md5 hash
>cd yourPC PATH_TO_Apps/Cogi/
>rem use whatever md 5 checker you have
>md5chk.py com.cogi.mobile.apk ee75eba0fef749dba8796c2eb5cab309
      file length: 12736720
    file checksum: ee75eba0fef749dba8796c2eb5cab309
expected checksum: ee75eba0fef749dba8796c2eb5cab309
True

Install the Downloaded APK on the Tablet

refs:

  1. Connect USB cable from tablet to pc
  2. Copy [drag & drop] com.cogi.mobile.apk
    From: yourPC PATH_TO_Apps/Cogi/
    Into: yourPC PATH_TO_Tablet/Tablet/Download
    N.B.: Navigate to yourPC PATH_TO_Tablet/Tablet/Download in your PC File Browser
    when your Tablet is USB connected.
  3. Disconnect USB cable from tablet to pc
  4. On Tablet Go to Menu > Settings > [General] > Security > and check “Unknown Sources”
    4.1 the cnet link ALSO says
    Menu > Settings > [General] > Security > and check “Verify Apps”
    “Depending on your device, you can also choose to be warned before installing harmful apps. This can be enabled by selecting the Verify apps option in the Security settings.” N.B. For me this was ALREADY CHECKED
  5. On Tablet go to My Files > Download
    N.B. “Downloaded Apps” is a Category NOT A FOLDER
  6. Tap com.cogi.mobile.apk
    [I notice that this app gets A TON of permissions – should have checked earlier]
  7. Tap Install
    RESULTS:
    – Cogi appears in “Downloaded Apps” Category
    – Cogi appears in the Apps Tab of the Top Screen
  8. IMPORTANT Go back to Menu > Settings > [General] > Security > and UNCHECK “Unknown Sources”

THE END

Uninstalling the Bing Bar, Surreptitiously Installed with Skype 5.8

Uninstalling the Bing Bar, Installed with Skype 5.8

Background

I got a Windows error message generated by BSvcProcessor.exe. I didn’t install this and so i did some research.

Research Links

This link contained “BSvcProcessor.exe”; it hooked up “BSvcProcessor.exe” with Bing Service, [Tom’s Hardware microsoft-bing-service…] (http://www.tomshardware.com/answers/id-2735458/microsoft-bing-service-bingsvc-exe.html)

Persuit of “Bing Service” searches produced “What is the Microsoft Bing Bar” from support.skype.com. This link said:

The Bing Bar is installed automatically when you install Skype 5.8 for Windows desktop.

Uninstall

So I uninstalled it.

To uninstall the Bing Bar:

Click Start - Control Panel.
Windows XP: Add or Remove Programs.
Windows Vista and 7: Uninstall a program.
Select Bing and click Uninstall.