{"id":1831,"date":"2014-01-14T09:13:27","date_gmt":"2014-01-14T17:13:27","guid":{"rendered":"http:\/\/www.wellgolly.com\/?p=1831"},"modified":"2014-03-25T17:54:36","modified_gmt":"2014-03-26T00:54:36","slug":"a-programmers-toolbox","status":"publish","type":"post","link":"https:\/\/www.wellgolly.com\/?p=1831","title":{"rendered":"A Programmers Toolbox"},"content":{"rendered":"<p>I spend most of my time in <b>Xcode<\/b> working on iOS apps. I just finished updating them to iOS7 and thought it would be fun to log all of the different programs that I use in the next week or so.<\/p>\n<p>I\u2019ll start by backtracking a bit. When proofing one app, a blank spot appeared where a picture should be. The most likely cause of that would be a mis-named picture or one that was completely missing. The names of the pictures are read from a database so I needed to check the names in the database with the names of the pictures. The database is on my server so I could open <b>phpMyAdmin<\/b> and check the names there, but in case the problem was in the <b>PHP<\/b> script that I used to create the app database, I decided to open <b>Firefox<\/b> and use the <b>SQLite Manager<\/b> plugin to look at the file that I actually use in the app. It turns out that one of the pictures was missing. I had an extra picture in my app so the total number was correct. I swapped the picture and the sounds and the app worked correctly.<\/p>\n<p>We put a frame around the drawings that show up on the screen in the apps. Most of the drawings are floating in space, so the size of the frame doesn\u2019t matter. Sometimes the drawing comes to the edge of the frame and the size of the frame is slightly different than the size of the picture. There is a couple of pixel wide band of whitespace that is out of place. We decided to extend the drawing to get rid of the white space between the picture and the frame. Our drawings are done in <b>Adobe Flash<\/b> and exported as .png&#8217;s. We usually have hundreds of drawings in our apps, so we reduce the size of them by using <b>ImageOptim<\/b>. I processed the new drawings and added them to the game.<\/p>\n<p>I had a minor issue in the app that I thought might be related to a change I had made earlier. I use <b>Git<\/b> for version control, so in <b>Xcode<\/b> I checked previous versions of the file to see if that was where the problem occurred.<\/p>\n<p>Once everything was proofed and submitted to Apple for review, I opened <b>GitX<\/b> to commit any files that Xcode missed. Xcode often misses deleted files. Then I opened <b>Terminal<\/b> and ran the <b>git push<\/b> command to synchronize my copy of the apps with the copy on the server.<\/p>\n<p>I use Apple\u2019s <b>iTunes Connect<\/b> website to manage my apps and check on daily sales. I checked to make sure all of the apps were waiting for review and I hadn\u2019t missed any uploads. <b>App Annie<\/b> lets me track revenue by product and over arbitrary time periods. I spent a couple of hours reviewing my sales and checking reviews. <\/p>\n<p>Checking the App Annie website doesn\u2019t require a lot of concentration so I decided to listen to some music. I\u2019ve been copying some of my LPs to disk so I can listen to them on my iPod or stream them with <b>iTunes<\/b> on my <b>AirTunes<\/b> network. I have a turntable hooked up to my Mac Mini using an old Roland UA-30 USB interface. I opened <b>Felt Tip\u2019s Sound Studio<\/b> and recorded a few LPs. Sound Studio is great for recording and cleaning up voice recordings and we use it all the time. It doesn\u2019t have filters for cleaning pops on LPs, so I opened <b>Audacity<\/b> to get rid of the pops and noise. Audacity is a good recording tool, but its workflow is arranged around projects and doesn\u2019t work well for cutting hundreds of sounds out of a recording session and saving them as .aiff&#8217;s. Sound Studio works well for our process. It\u2019s also great for marking and exporting songs from an LP.<\/p>\n<p>I often help other people with their websites and today I got a request to update some data in an SQL file on another persons server. I usually use <b>phpMyAdmin<\/b> to work with <b>MySQL<\/b> files, but they don\u2019t have it installed on their server, so I needed to either work on the command line or find another way to work with the database. I can work on the command line, but I really don\u2019t like to. Oracle now owns MySQL so I went to their website and downloaded <b>MySQLWorkbench<\/b>. It took a while to figure out how to use it but it works fine. The person giving me the data didn\u2019t know how to get it out of his spreadsheet and into a flat file, so I opened the spreadsheet in <b>LibreOffice<\/b> and exported the worksheets as comma-delimited text. The format of the data wasn\u2019t the same as the format in the database so I used <b>BBEdit<\/b> to clean up the data. BBEdit has a search and replace feature that uses <b>grep<\/b> and it only took a few minutes to rearrange the file into something that could be imported into MySQL. I documented that process in a previous <a href=\"http:\/\/www.wellgolly.com\/?p=1823\">post<\/a>. Since I hadn\u2019t used MySQLWorkbench before, I opened a database on a Digital Ocean droplet that my nephew is using for learning web development. That way if I did something really dumb to the database, it wouldn\u2019t affect a production server. Once I got the update working properly\u2014the handoff had some issues that needed to be fixed was ready to update the database. I always make a copy of every table before I update it and phpMyAdmin has a button to push to do that. I couldn\u2019t find a menu item or button in MySQLWorkbench, so I duplicated my test table on the Digital Ocean server using phpMyAdmin and looked for the sql code that it used. <\/p>\n<p><pre><code class=\"preserve-code-formatting\">\nCREATE TABLE&nbsp;&nbsp;`Customer1`.`values_Air_Temp_BAK` (\n`id` INT( 8 ) NOT NULL AUTO_INCREMENT ,\n `datetime` DATETIME DEFAULT NULL ,\n `value` FLOAT DEFAULT NULL ,\n `source_type_id` INT( 11 ) DEFAULT NULL ,\nPRIMARY KEY (&nbsp;&nbsp;`id` ) ,\nUNIQUE KEY&nbsp;&nbsp;`datetime` (&nbsp;&nbsp;`datetime` )\n) ENGINE = MYISAM DEFAULT CHARSET = utf8;\n\nSET SQL_MODE =&nbsp;&nbsp;&#039;NO_AUTO_VALUE_ON_ZERO&#039;;\n\nINSERT INTO&nbsp;&nbsp;`Customer1`.`values_Air_Temp_176_BAK` \nSELECT * \nFROM&nbsp;&nbsp;`Customer1`.`values_Air_Temp_176` ;\n<\/code><\/pre><\/p>\n<p>I pasted this code into MySQLWorkbench on the production server and had my backup.<\/p>\n<p>I updated the data in the backup and had the user check it for egregious errors. Once it was validated I again used the test server to get the code to rename the backup.<br \/>\n<pre><code class=\"preserve-code-formatting\">\nRENAME TABLE&nbsp;&nbsp;`Customer1 `.`values_Air_Temp` TO&nbsp;&nbsp;`Customer1 `.`values_Air_Temp_OLD`;\nRENAME TABLE&nbsp;&nbsp;`Customer1 `.`values_Air_Temp_BAK` TO&nbsp;&nbsp;`Customer1 `.`values_Air_Temp`;\n<\/code><\/pre><br \/>\nI had the user double check that everything looked right and I was done with that task.<\/p>\n<p>By the way, this blog is hosted on my server using <b>WordPress<\/b>. I host several blogs and they need updated from time to time. I can never remember the exact steps to do it (I should write a <b>bash<\/b> script to update them) so I keep the instructions and code in a wiki on our server. <b>Trac<\/b> is good for keeping notes on procedures and processes and we use it for bug reports when we are testing the software.<\/p>\n<p>I\u2019m managing four servers now and I\u2019ve been meaning to automate some of the process. Since I had some down time, I decided to refresh my <b>bash<\/b> skills and write some scripts. I especially wanted to automate the login process to different servers and color code the prompts so it was clear where I was. I\u2019ve also been trying out <b>iTerm2<\/b> as a terminal.<\/p>\n<p>I just got a call from my nephew about his server. He\u2019s been playing with <b>PHP<\/b>, <b>CSS<\/b>, and <b>JavaScript<\/b> and messed up a couple of files. I have the originals on my machine, so I opened <b>Cyberduck<\/b> and uploaded them to his server. Cyberduck is an OSX only program, so he uses <b>Filezilla<\/b> on his Ubuntu Linux machine. It works on OSX, but the Cyberduck interface is more \u201cMac like\u201d. I showed him how to use the W3C <a href=http:\/\/validator.w3.org\">validator tools<\/a> to check his code for errors. It\u2019s a lot easier to figure out why your HTML and CSS isn\u2019t doing what you want if you don\u2019t have any errors in it. <\/p>\n<p>After I wrote the script to log me in to all the machines I use, I set up SSH authorized keys so that I don\u2019t have to type the password each time. I\u2019m not sure that I would do this with a laptop that I carry around, but I\u2019m using a Mac Mini and it rarely leaves the house. I need to copy my public key to a file called authorized_keys in my .ssh directory on each machine. I could use Cyberduck, but the <b>scp<\/b> command works better.<br \/>\n<pre><code class=\"preserve-code-formatting\">\nscp ~\/.ssh\/RSA_KEY.pub me@192.168.102.113:\/home\/me\/.ssh\/authorized_keys\n<\/code><\/pre><\/p>\n<p>I updated my .bash_config script so that I have a function that copies my config files to all the machines I use. It uses the same scp command, except that it copies the file from my mini to all of the servers. Since I just updated all of them to use secure authorization, no passwords are required for it to work.<br \/>\n<pre><code class=\"preserve-code-formatting\">\nid=$(who am i | cut -d\\&nbsp;&nbsp;-f 1)\nserver=&#039;192.168.194.220&#039;\ndave=&#039;192.168.201.11&#039;\ndon=&#039;192.168.102.113&#039;\npurple=&#039;purple.someserver.com&#039;\n\n# Update the list of servers if you add one. It is used on connect and scp functions\nservers=(server dave don purple)\n\n# Share .bash_config. Requires . ~\/.bash_config in .bash_profile\nshare() {\n&nbsp;&nbsp;&nbsp;&nbsp;\n&nbsp;&nbsp;&nbsp;&nbsp;# This works if you want to list out each server\n&nbsp;&nbsp;&nbsp;&nbsp;# But if you add new servers, you need to remember to update this list\n&nbsp;&nbsp;&nbsp;&nbsp;# scp .bash_config ${id}@${server}:.bash_config\n&nbsp;&nbsp;&nbsp;&nbsp;# scp .bash_config ${id}@${dave}:.bash_config\n&nbsp;&nbsp;&nbsp;&nbsp;# scp .bash_config ${id}@${don}:.bash_config\n&nbsp;&nbsp;&nbsp;&nbsp;\n&nbsp;&nbsp;&nbsp;&nbsp;# This is better because the list of servers isn\u2019t hard coded in the script \n&nbsp;&nbsp;&nbsp;&nbsp;for serv in &quot;${servers[@]}&quot;; do\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;Connecting to $serv&quot;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scp .bash_config ${id}@${!serv}:.bash_config\n&nbsp;&nbsp;&nbsp;&nbsp;done\n}\n<\/code><\/pre><\/p>\n<p>Every morning, I open my php_error.log file with <b>BBEdit<\/b> to see if I have any php or MySQL errors. I started getting lots of <a href=\"http:\/\/www.wellgolly.com\/?p=1707\">weird errors<\/a> a while ago and it turns out they are MySQL injection attacks. I fixed the code and tracked the attempts for a while, but since it seems to be working now, I no longer log them.<\/p>\n<p>I just took some pictures of unusual cloud formations, and posted them on a flying blog that I run. I like to use <b>Image Capture<\/b> to grab the images from the camera and then crop and resize them in <b>Acorn<\/b>. Though it\u2019s not related to work right now, we often we often use the same process to get images for apps. Some of the members of the team use <b>Adobe PhotoShop<\/b> to fix the images, but my version doesn\u2019t run on OSX Mavericks, so I only use it when I\u2019m using my laptop.<\/p>\n<p>I also use some apps that are not directly related to programming. I just got a couple of orders for CDs so I opened the <b>FileMaker Pro<\/b> database on my laptop to process the order. This is a really old version of FileMaker that won\u2019t run on Mavericks. But it still works fine and I don\u2019t need any of the newer features. We used to use FileMaker more for developing the wordlists and text for our games, but we moved most of that to the web using PHP, MySQL, and a bit of JavaScript. That way people can work on the database without having to use sneaker-net to get the correct database. One of my goals for the year is to update the database so that it runs in LibreOffice. I use <b>Square<\/b> on my iPod to process credit cards and <b>Stripe<\/b> to process cards from international sales.<\/p>\n<p>Our CD burning robot is also very old and runs on a PPC Mac Mini using <b>PTPublisher<\/b>.<\/p>\n<p>So that\u2019s about it for a fairly normal week.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I spend most of my time in Xcode working on iOS apps. I just finished updating them to iOS7 and thought it would be fun to log all of the different programs that I use in the next week or so. I\u2019ll start by backtracking a bit. When proofing one app, a blank spot appeared &hellip; <a href=\"https:\/\/www.wellgolly.com\/?p=1831\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">A Programmers Toolbox<\/span><\/a><\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-1831","post","type-post","status-publish","format-standard","hentry","category-coding"],"_links":{"self":[{"href":"https:\/\/www.wellgolly.com\/index.php?rest_route=\/wp\/v2\/posts\/1831","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wellgolly.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wellgolly.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wellgolly.com\/index.php?rest_route=\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wellgolly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1831"}],"version-history":[{"count":0,"href":"https:\/\/www.wellgolly.com\/index.php?rest_route=\/wp\/v2\/posts\/1831\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wellgolly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1831"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wellgolly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1831"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wellgolly.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1831"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}