tag:blogger.com,1999:blog-76294382180387332602024-02-20T04:04:26.075-07:00Code BJournal - Matt DyerMatt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.comBlogger46125tag:blogger.com,1999:blog-7629438218038733260.post-34192325711223709572021-10-25T14:01:00.003-06:002021-10-25T14:01:53.890-06:00Coding<p> </p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDCailhTybGTDVX6pb6xE7rpwmEcP3TFRJ_-CUhkvFMi1i2AtdnmElydNwNT4s4aTWofQkmnAqxlLB6O38Mswe4WjD3WlYVRT0W4g7SJDGWa5YF0UibTpOaIwrl7f0MSSbejxH23ehkok/s2048/moon_rising.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1536" data-original-width="2048" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDCailhTybGTDVX6pb6xE7rpwmEcP3TFRJ_-CUhkvFMi1i2AtdnmElydNwNT4s4aTWofQkmnAqxlLB6O38Mswe4WjD3WlYVRT0W4g7SJDGWa5YF0UibTpOaIwrl7f0MSSbejxH23ehkok/s320/moon_rising.jpg" width="320" /></a></div><br />I'm not sure where I heard this, and it wasn't worded this way, but it helps to think about coding this way.<p></p><p>Basically, any program you write is just meant to translate your problem into an already solved problem in computer science, or put another way, translate your input data into data that can be passed to an existing algorithm.</p>Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-28757647483319440582021-09-28T13:57:00.001-06:002021-09-28T13:57:30.058-06:00Python Particle Simulation Update<p> I don't have much to update about, other than the fact that the simulation still makes sense. I haven't run into any problems that will prevent me from completing it. I think I have found some python libraries that will help me in calculating intersection and with graphically displaying the simulation. Currently I am using the following:</p><p>Pyglet - for graphics and possibly for timing of events</p><p>Sympy - for calculating intersection of particles using Rays</p><p>That's about all that is happening in my coding life right now.</p>Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-6633516491767589762021-09-16T14:19:00.000-06:002021-09-16T14:19:22.721-06:00Python Particle Simulation<p> I have started working on a particle simulator in python. I have limited knowledge of Quantum Mechanics, but thinking about the weird way particles and entanglement work has lead me to some ideas that I want to try in a computer simulation of particles. My idea is that certain properties not existing, or being described by probability functions will allow the simulation to run very fast with large numbers of particles.</p><p>I have been thinking about this for several years and made other attempts to get started. The current attempt is the furthest I have ever gotten. I have finally gotten it clear in my head what I want to do.</p><p>I am going to setup an array of particles. Each particle will have a position and a direction. When 2 particles interact I will optionally create more particles and select new directions for each particle. At that point I will, using the direction of each particle, look for future interactions with other particles. These interactions will go onto a queue that will be processed starting with the earliest event in time.</p><p>My thought is that doing this will mean that I only need to loop over the particles when an interaction happens, not for every frame like you would in a traditional animation type program.</p><p>I still haven't worked out all the details. It is possible that it just doesn't work, or doesn't make sense in some way.</p>Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-32454260850457810362020-03-18T11:55:00.003-06:002020-03-18T11:55:53.164-06:00Canvas PaintHere is another small JS project that I built quite a few years ago. It was basically just an exploration of the canvas tag, which was somewhat new at the time. I called it "<a href="https://projects.mattdyer.us/canvaspaint/index.html" target="_blank">Canvas Paint</a>". It allows you to draw on the canvas. You can change the color and width of the brush by changing the numbers in the boxes and clicking either "Set Color" or "Set Width".<br />
<br />
<a name='more'></a><br />
<br />
When you're done drawing you can click "Get Image". This gets the base64 source of the image from the canvas and sets it as the src of an image tag at the bottom of the page so you can download the image.<br />
<br />
There are various other controls that allow you to adjust the color of your whole image in various ways. You can see the code below that shows what all these controls do.<br />
<br />
<br />
<br />
<script src="https://gist.github.com/mattdyer/1460c60516a2a1b3d505d271f80df5a4.js"></script>Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-13484431564111358952020-03-11T14:30:00.000-06:002020-03-11T14:32:01.614-06:00Life GamePreviously I posted about a game (really a simulation) that I made several years ago. I called it the <a href="https://projects.mattdyer.us/fish/index.html" target="_blank">Fish Game</a>. A few years later I made another very similar simulation that I called "<a href="https://projects.mattdyer.us/life/index.html" target="_blank">Life Game</a>".<br />
<br />
It is similar, but quite a bit more complex, and I think somewhat better written code. In this version there are three life forms; fish, bugs, and plants. The fish eat the bugs. The bugs eat the plants. The plants gain energy each frame as if they are getting energy from the sun. Each life form has a fairly large set of properties. These are copied to the individual life forms as they are created.<br />
<br />
<a name='more'></a><br /><br />
When the simulation is running you can modify these properties for the entire species, or the individuals. In this simulation the offspring are created near the coordinates of the parents. This creates a nice affect where the plants appear to slowly spread across the game area.<br />
<br />
The code is also setup so that it would be easy to add other life forms. I didn't build that into the simulation. I think it would be easy to do though, and I may create an updated version at some point. I'm think of converting the whole thing into a phone app, but we'll see if that happens.Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-75565536617376535042020-03-03T18:32:00.004-07:002020-03-03T18:33:05.985-07:00Custom Thumbnails for Magento 2 ProductsI recently migrated a site from Magento 1 to Magento 2. The product image thumbnails work differently in Magento 2. In Magento 2 they use a JS library called <a href="https://fotorama.io/" target="_blank">Fotorama</a>. It has several options that can be modified in the view.xml if you have a custom theme setup. However, none of the thumbnail options match the way that the thumbnails work in Magento 1, and my client wanted them to look more like the old version.<br />
<br />
<br />
<a name='more'></a><br />
<br />
I ended up overriding the view/frontend/templates/product/view/gallery.phtml file from the magento/module-catalog module. In that file I was able to add some custom code that outputs more traditional looking thumbnails. With some simple JS I was able to make clicking on those thumbnails switch the main Fotorama image.<br />
<br />
Below is a quick example of the file. I have changed it a bit from my production version. Mostly just cut out some extra code I had in there. I started with a copy of gallery.phtml from Magento 2.2.4, I believe. This file has changed somewhat in the latest version, but the basic idea of this technique should still work. Basically I am getting the images JSON that is used by Fotorama. Then I convert it back to a php array. Then I loop over it at the bottom and output divs with the thumbnails and image captions in them. I also have some css for those that I didn't include here. Leave a comment if anyone wants to see that. There is also some JS that adds a click event to the thumbnails that finds the Fotorama slideshow and switches to the correct image.<br />
<br />
In my theme I also added an etc/view.xml file. I copied the contents from vendor/magento/theme-frontend-blank/etc/view.xml and changed the thumbnail setting to just show dots instead of the thumbnails that Fotorama shows by default. You can also turn the default thumbnails off all together if you want to.<br />
<br />
<br />
<br />
<script src="https://gist.github.com/mattdyer/c722af2c7d0f59f82ae40faf71b83dc2.js"></script>Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-57617137185564713262020-02-28T10:17:00.002-07:002020-02-28T10:18:22.426-07:00Fish GameMany years ago, probably about twelve to fifteen, I was working on building a custom e-commerce system using Adobe Coldfusion. I was a young developer and so were the rest of the developers I worked with. Non of us were really qualified to build such a complex system, but we didn't know that, so we did it anyway. It ended up working fine for the customers we had. I'm sure I would not be happy with most of the code if I saw it today.<br />
<br />
<br />
<a name='more'></a><br /><br />
<br />
As part of the project we needed to build in product sorting. I came up with an idea that looked good, but in the end was not practical. You could choose to sort the products by name, price etc. and when you chose an option the page would move the products around using javascript. In the end this was all abandoned for a more practical version of sorting that reloaded the page.<br />
<br />
However, from the code I had written for this I created a game. I called it the Fish Game. Basically there is a square game area and you can add food and fish. The food is added at a random location and the fish always start in the upper left corner. The fish move towards the food and when they get close enough they "eat" the food.<br />
<br />
Each fish has a maximum speed and an amount of life energy. The faster the fish moves the more energy it uses up. When a fish eats food it gains energy. When a fish collects enough energy it will spawn a new fish. The new fish will be randomly a little slower or faster than the parent fish. As time goes on the fish get faster and faster because the fastest ones always get the food. Eventually they reach a point where they are using too much energy moving and they cannot get to the next piece of food before running out of energy.<br />
<br />
Below is a link to the game if you want to try it out.<br />
<br />
<a href="https://projects.mattdyer.us/fish/index.html">https://projects.mattdyer.us/fish/index.html</a>Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-68780578186755682162020-02-26T10:58:00.001-07:002020-02-26T10:58:07.507-07:00Playing Local Network Media on a Chromecast with PythonI have several Chromecast devices in my house. Recently I was playing around with the Python module pychromecast. It has given me a much better understanding of what the Chromecast does. The module allows you to find devices on your network and play videos or other media on the device.<br />
<br />
<a name='more'></a><br />
<br />
This is done simply by finding the device and giving it a url and mime-type for the media that you want to play. After seeing the example it seemed like it should be possible to play media from a server on my local network.<br />
<br />
The example code has this line:<br />
<br />
mc.play_media('http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', 'video/mp4')<br />
I found an .avi video file and quickly started a python web server in the folder with the video on my machine. I added a server folder to the project with an index.html file and a test.avi file. Then I navigated to the folder in Terminal and ran this.<br />
<br />
python -m http.server<br />
<br />
Then I could see my index.html file here: http:/localhost:8000<br />
<br />
After I had the server working I modified the example code to send the url to the video file using my local network IP address. This almost worked. I got sound, but no video and I got an error on my web server when I tried to pause it. I think some of the requests the Chromecast was making to the server were not supported by the python web server. This may not be an issue if I used Apache or some other standard web server.<br />
<br />
Right now I have a Plex media server setup, but there are some limitations with that when casting from the Android app with a free account. At some point maybe I will try to build something that uses this to play my movies. I'll have to experiment a bit more and see why I wasn't getting video. It may have just had something to do with the video encoding of the file I was testing with. It is possible it is also a web server related issue.<br />
<br />
The code I used is on Github here: <a href="https://github.com/mattdyer/chromecastcontrol">https://github.com/mattdyer/chromecastcontrol</a>Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-24938801925058969732019-04-30T20:13:00.000-06:002020-02-26T15:33:35.750-07:00Using BraveFor a few weeks now I have been using the <a href="https://brave.com/" target="_blank">Brave</a> browser. It is based on <a href="https://www.chromium.org/" target="_blank">Chromium</a>, so switching from <a href="https://www.google.com/chrome/" target="_blank">Chrome</a> was a quick adjustment since I have been using Chrome for years. Brave includes an ad blocking system that blocks what they call "very intrusive ads" and most attempts to track users across sites. They have also setup a system using <a href="https://basicattentiontoken.org/" target="_blank">BAT</a> currency that allows you to directly pay content providers that you visit. I have also setup my site as a content provider so I can receive tokens.<br />
<br />
<br />
<b>Browser</b><br />
<b><br /></b>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUptZPR6YPlZzfz2LJA4-wkraKMNjTMKuRe1pikuFaUnqf2l5x7xyfo85v5xlKM-U-WQpoH4kcFtegwcfvJU51pLyPVijLWrKKMZpArDLQUX1f-XOrAlpwuiRNfKQO6ASrpZrWyDAvC7s/s1600/Screen+Shot+2019-04-30+at+7.35.01+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="140" data-original-width="138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUptZPR6YPlZzfz2LJA4-wkraKMNjTMKuRe1pikuFaUnqf2l5x7xyfo85v5xlKM-U-WQpoH4kcFtegwcfvJU51pLyPVijLWrKKMZpArDLQUX1f-XOrAlpwuiRNfKQO6ASrpZrWyDAvC7s/s1600/Screen+Shot+2019-04-30+at+7.35.01+PM.png" /></a></div>
<b><br /></b>
<br />
The browser was created by Brendan Eich, the creator of Javascript. The browser has worked well so far. It updates automatically similarly to the way Chrome does. They have a system for syncing bookmarks between your devices. You also have a wallet built in for your BAT tokens. I am using it on a Mac, and my Android phone.<br />
<br />
<br />
<br />
<a name='more'></a><br /><br />
<b>Ads</b><br />
<br />
The creators of the browser have also setup an ad network. There are several ad providers involved, but I haven't looked into this too much yet. These ads will be shown by the browser in cases where other ads were hidden and maybe in other cases. You get paid in tokens for viewing the ads. I have that turned on, but I haven't received any tokens yet.<br />
<br />
<br />
<b>Brave Rewards</b><br />
<br />
The wallet and the system for paying other sites is called Brave Rewards. The wallet can currently be synced between desktop systems. They haven't added that ability to the Android version, but they say it will be added soon. I got a 20 BAT grant for using the Android version but I can't currently use those on the desktop version. Maybe they are doing that on purpose to get more mobile use.<br />
<br />
<br />
<b>Content Providers</b><br />
<br />
Getting setup as a content provider took several steps, but it was mostly painless. First you setup a <a href="https://publishers.basicattentiontoken.org/publishers/home" target="_blank">Brave Rewards provider account</a>. Then you have to link that to an account at a site called <a href="https://uphold.com/" target="_blank">uphold.com</a>. I hadn't heard of that site before. To fully verify your account with UpHold you have to provide a physical address and a picture of a valid ID. I was a little worried about providing that, but after a little research I decided it seems to be a legitimate site.<br />
<br />
<br />
Overall it seems like a pretty cool browser, and I hope the advertising and payment system work out. It seems like a much better way to pay for content on the web. The advertising on many sites has gotten out of hand.<br />
<br />Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-71424724804560874382018-04-17T21:08:00.002-06:002020-02-26T15:34:24.621-07:00Using The Coldfusion XMLValidate Function To Validate User ContentSometimes you want to allow a limited set of HTML tags in user generated content. This can be done with the <a href="https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-t-z/xmlvalidate.html">XMLValidate</a> function in Coldfusion as long as the content is valid XHTML.<br />
<br />
Several years ago I read an article about <a href="https://www.bennadel.com/blog/2004-Escaping-Form-Values-Understanding-The-ColdFusion-htmlEditFormat-Life-Cycle.htm">escaping form values</a> posted by Ben Nadel on his site <a href="https://www.bennadel.com/">www.bennadel.com</a>. Some discussion came up in the comments about allowing a limited set of html tags for paragraphs, bold text, and so on. I had a need to do this for forum comments on a site that I was working on. This site was written in Coldfusion so I was looking at some of the same options mentioned in Ben's article. I ended up doing something a little different though.<br />
<br />
We were using <a href="https://www.tinymce.com/">TinyMCE</a> for the forum comments. TinyMCE produces XHTML code so I was able to use Coldfusion's abilities to handle XML to accomplish this task. Using the <a href="https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-t-z/xmlvalidate.html">XMLValidate</a> function and an XML schema that was modified to accept a small list of tags and attributes the comments were correctly limited. Here is the relevant portion of the code. Below is an explanation of how it works. <br />
<br />
<br />
<a name='more'></a><br /><br />
<script src="https://gist.github.com/mattdyer/e380d38275946d1e2d07a9f7a44da2a3.js"></script>
<br />
The first line takes the content from the form and wraps a content tag around it. This is done because valid XML has to have a root element. Naming this element content was just an arbitrary decision. It could have been anything. Also before parsing non-breaking spaces are escaped in the content. If I remember right the non-breaking spaces were causing the <a href="https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-t-z/xmlformat.html">XMLFormat</a> function to error.<br />
<br />
The next section is a cfxml tag containing the XML schema. This XML was created from some examples and then modified to include the desired tags.<br />
<br />
The schema allows the following tags:<br />
<br />
<ul>
<li>any number of br, strong, em, ul, ol, u, strike, li, spans with style and class attributes, </li>
<li>a tags with href, title, target, and class attributes, </li>
<li>img tags with src, alt, height, and width attributes, </li>
<li>p tags with align, class, and style attributes, </li>
<li>and finally content tags </li>
</ul>
<br />
<br />
As mentioned above the content tag is just a container added to act as the root document element. Also the href attribute on a tags can only contain urls not javascript.
<br />
<br />
Then XMLValidate is called with the content and the schema. This returns a struct with information about the validity of the document. Finally the status key is used to decide if the content is acceptable or we need to reject it.
<br />
<br />
This article was rewritten from an article that I wrote several years ago on a different blog. That blog is no longer online. I think the information is still useful though. I have a few other articles from that old site that I am going to re-publish.Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-21769146465735334382018-04-15T14:00:00.001-06:002020-02-26T15:34:50.322-07:00Setting Up an Angular 5 site on Github Pages<span style="font-size: large;"><b><u>Getting Started</u></b></span><br />
<br />
This article will go over all the steps to setup an Angular site on GitHub pages. The site will use <a href="https://angular.io/guide/aot-compiler">Angular's AOT compiling</a> and be served from the docs folder of the repository.<br />
<br />
To start with you can follow the guide here to <a href="https://angular.io/guide/quickstart" target="_blank">setup a new Angular project</a>. Then you will need to <a href="https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/" target="_blank">setup a repository</a> on <a href="https://github.com/">Github.com</a>. The name of the repository doesn't matter, this site will use the docs folder, not the specially named repository with USERNAME.github.io as the name.<br />
<br />
<a href="https://www.blogger.com/null" name="more"></a><br />
<a name='more'></a><br /><br />
<br />
<span style="font-size: large;"><b><u>Project Changes</u></b></span><br />
<br />
After that open up the project in your editor and open the .angular.cli.json file. Change the "outDir" to "docs". This is where the files will be created when you build the project. The contents of .angular.cli.json are shown below with all the changes discussed in the article.<br />
<br />
<span style="font-size: large;"><b><u>Custom Domain</u></b></span><br />
<br />
To use a custom domain for your site you need to create a file name CNAME that contains only the domain name. The <a href="https://help.github.com/articles/using-a-custom-domain-with-github-pages/">GitHub help page</a> explains how to setup DNS and everything else you need for this. Create the file in the src folder of your project. Then you need to add "CNAME" to the "assets" setting in your .angular.cli.json. You can see this in the example file below.<br />
<br />
If your site is using routing and you want the links to pages, other than the home page, to work you will need to setup a custom 404 page on your GitHub site. There is a help <a href="https://help.github.com/articles/creating-a-custom-404-page-for-your-github-pages-site/">document here</a> explaining how to do that. If all you do is add a custom 404.html file to the site it still won't make your links work. For the Angular site to work correctly the easiest way is for your 404.html file to be the index page of your site. In your src folder make a 404.html file and copy the contents of the index.html file into the 404.html file. Then in the .angular.cli.json change the "index" setting to 404.html.<br />
<br />
This is the .angular.cli.json with all the changes.<br />
<br />
<script src="https://gist.github.com/mattdyer/03b703d63d6d4cfbc0a16914c970487f.js"></script>
<br />
<span style="font-size: large;"><b><u>Site Setup</u></b></span><br />
<br />
Now you are ready to build the site and commit all the changes. Run the following command in your project folder:<br />
<br />
ng build --aot --prod --env=prod<br />
<br />
This should create a docs folder with files similar to the following:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizudL-N-yiloXZir-09YprbZl7KZrXXVDbax99tsx_uABrproCIsHbujtuwYBWm7K3fUpVcjD2sNMPqs3qFNTuXg6btYxTbsvGv0EXdyu7rTaH0c54XhcOMO0uSihyphenhyphenkZ4nOfE5Tfck3es/s1600/docs-folder.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="199" data-original-width="307" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizudL-N-yiloXZir-09YprbZl7KZrXXVDbax99tsx_uABrproCIsHbujtuwYBWm7K3fUpVcjD2sNMPqs3qFNTuXg6btYxTbsvGv0EXdyu7rTaH0c54XhcOMO0uSihyphenhyphenkZ4nOfE5Tfck3es/s1600/docs-folder.jpg" /></a></div>
<br />
<br />
Then you need to add all the changed files and commit everything. Run the following commands to send everything up to GitHub.<br />
<br />
git add .<br />
git commit -m 'initial commit'<br />
git push<br />
<br />
At GitHub.com on your repository there is a Settings section. Scroll down to the GitHub pages section. Change the Source dropdown to the "master branch /docs folder" option. After this your site should be up and running. You can access it at your custom domain if you set one up, or the standard GitHub url for your repository.<br />
<br />
Here is the output of "ng --version" for the setup used for this article. Things could change as time goes on, but I am happy to answer any questions in the comments below. Let me know if anyone has handled the index.html / 404.html situation differently.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9rFgp0S9mEGgsFmHhDdkBEBdsmDCHhtfEtgue3De_064WsVbUDkdkHnxIsF3dm2rWqIUAKcn0C23c7DBY7km__C_zuZsxdDSuc9gOo9EXDISRPkgeP45eugQgg5ohyLq4i09Vxcf0ECs/s1600/angular-versions.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="370" data-original-width="442" height="267" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9rFgp0S9mEGgsFmHhDdkBEBdsmDCHhtfEtgue3De_064WsVbUDkdkHnxIsF3dm2rWqIUAKcn0C23c7DBY7km__C_zuZsxdDSuc9gOo9EXDISRPkgeP45eugQgg5ohyLq4i09Vxcf0ECs/s320/angular-versions.jpg" width="320" /></a></div>
<br />Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-57145587912454106322018-04-13T13:43:00.000-06:002018-04-13T13:43:39.342-06:00Listening For JS Error Events<div dir="ltr">
I was recently reading a blog article, <a href="https://www.bennadel.com/blog/3429-tracking-image-error-events-using-event-delegation-in-javascript.htm" target="_blank">Ben Nadel JS Error</a>. In the article Ben showed how to setup an error <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener" target="_blank">event handler</a> that would be triggered for any failed image loads on a page. This was done by attaching an error event handler to the body element. Also he had to pass the last argument to addEventListener as true so that it would trigger in the capture phase of the event. This event handler will run whenever an external resource like an image or a style sheet fails to load on the page.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
After some experimenting I found that if I attach the event to the window object it is triggered for all the failed resources and also for any javascript errors that happen on the page. Setting this up on a site with quite a bit of traffic from different browsers was very interesting. It was a bit overwhelming at first until some things were fixed and some checking was added to filter out some of the errors. In the event handler the event and error information is being posted back to a server and then sent in an email so it can be reviewed.<br />
<br />
<br />
<a name='more'></a><br />
<br />
<br />
Several errors showed up right away in IE Edge. These were things that were looking for IE user agents and doing IE specific things. Once those were fixed some failed loads for the Google ananlytics script started showing up in Firefox. After doing a little testing I realized that Firefox blocks that script from loading if you have the "Do Not Track" option turned on. An error event is still generated, however, so the script was modified to skip those errors.<br />
<br />
I went through several iterations of the script sending different information from the error event object. Currently this is the script that is being used:<br />
<br />
<br />
<script src="https://gist.github.com/mattdyer/43d596bcd6d45e7864e7a1e124f31d09.js"></script>
Initially <span style="background-color: #eeeeee; font-family: "courier new" , "courier" , monospace;">values</span> is set to contain the location of the current page so that information will always be available. Then if the event contains an error object the stack and message are set into <span style="background-color: #eeeeee; font-family: "courier new" , "courier" , monospace;">values</span>.<br />
<br />
Then all keys in the event object are looped over to get all the values. If the value has an outerHTML method then that is called to get the value. I'm using slice to limit the size of the outer HTML in case it is a large element containing many other elements. Otherwise if the value contains a toString method then that is called.<br />
<br />
After that the <span style="background-color: #eeeeee; font-family: "courier new" , "courier" , monospace;">values</span> object is converted to JSON. This is only used as an easy way to filter out the analytics errors that are generated in Firefox. Finally the results are posted to the server. On the server those values, along with some other information from the post request like the user agent, are emailed.<br />
<br />
It has been pretty interesting to see all these errors. I still need to filter some things out and try to get some more information about some errors that don't seem to have a cause. I think it will be very valuable to have this going forward.<br />
<br />
<br />
<br />
<br /></div>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-50130636135221601482018-04-11T15:51:00.002-06:002018-04-12T19:51:24.295-06:00My First Memories of CodingThe first time I remember writing code was in grade school in the computer lab. We were learning Basic. I'm not sure how old I was, but it would have been sometime in the late '80s or early '90s. I remember they had us write a program that would take some numbers from the user and print out the average. I had to ask how to do division. I had only seen it with the standard division symbol in math class, not the forward slash. Soon after that I was able to get Basic on my home PC. Actually I think it was included in MS-DOS.<br />
<br />
At school and in the beginning at home I was using Basic where you had to use line numbers to write your code. Then to edit a line you had to retype that line with the number. Soon after that I was able to get <a href="https://en.wikipedia.org/wiki/QBasic" target="_blank">QBasic</a> and a book to help me get started.<br />
<br />
<br />
<a name='more'></a><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidHH1AaG0oc06UJIhMLppEQ8QaQVOS7n33TvXKgCrZHmY_udLHRnW2zC52cfxvIhAXHIjg4_ZF7tk9yBJ0pK5pJMjQyv-YRHZHDpZXLzdNn3AEYWXZiMf4plgcxlc_ep-y8H7H8nBfKGk/s1600/QBasicBook.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="267" data-original-width="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidHH1AaG0oc06UJIhMLppEQ8QaQVOS7n33TvXKgCrZHmY_udLHRnW2zC52cfxvIhAXHIjg4_ZF7tk9yBJ0pK5pJMjQyv-YRHZHDpZXLzdNn3AEYWXZiMf4plgcxlc_ep-y8H7H8nBfKGk/s1600/QBasicBook.jpg" /></a></div>
<br />
<br />
I went through the book and wrote several programs of my own. I was always interested in writing some kind of a chat bot. I was able to get one working in QBasic, but it wasn't until quite a few years later that I wrote something that actually worked well. That one was written in perl, but I'll save that for another article.<br />
<br />
<br />
Before this most of what I had done on computers was related to homework, or gaming. I did quite a bit of fiddling with settings in Autoexec.bat and config.sys files, and whatever else needed to be done to get games to run. So that probably laid some groundwork for understanding variables and some other basic concepts of how a computer works.<br />
<br />
I'm going to write a few other articles on my early experience with coding, and how I started doing it professionally. Hopefully these will be completed over the next couple months.<br />
<br />
<br />
<br />Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-17190319486936728382017-03-05T21:48:00.001-07:002017-03-11T18:14:48.411-07:00Using IR codes from Broadlink backup fileThis is a continuation of yesterdays post about the Broadlink RM2 wifi remote. I was able to test out using the codes to control my remote today. They are stored in JSON format in the broadlink backup file. The backup file is a zip file. After you extract it there is a folder named SharedData. There are several files in the folder. The one that seems to have all the codes is named jsonIrCode. The data looks like an array of objects, each with a code and some other information.<br />
<br />
<br />
<a name='more'></a><br /><br />
<br />
<br />
<a href="https://www.blogger.com/null" name="more"></a><br />
<br />
<br />
The codes are an array of numbers that can be converted to a byte array. They are stored as signed integers and python seems to need unsigned so they need to be converted. I wrote this code today to test them out. This code isn't great, but it works to test the codes to see if they work. I think I'm doing the byte conversion correctly. Some of my codes seemed to work and others didn't. I didn't get much time to work on it today though. The broadlink library came from here https://github.com/mjg59/python-broadlink<br />
<br />
<span style="background-color: #ffe599;">Edit: I fixed a problem with this code converting the negative values in the arrays to positive values. All the codes from my saved file work now,</span><br />
<br />
<script src="https://gist.github.com/mattdyer/083e5a6ea1d886de7b9bb67b23291997.js"></script>
Also here is some more information about how I got the backup file from the eControls app. I used an app on my android phone named Packet Capture. I started the capture and restored a backup in the eControls app. Using what I got from that I was able to get the file using python. Here is the code for that. The values for the params and headers will need to be filled in with your own information.<br />
<br />
<script src="https://gist.github.com/mattdyer/2631580b72d266992b3e896baf6eed4f.js"></script>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com1tag:blogger.com,1999:blog-7629438218038733260.post-31966517442589573012017-03-03T22:09:00.001-07:002017-03-05T21:23:16.376-07:00Python control of Broadlink RM2 wifi remote<div dir="ltr">
I recently got a Broadlink wifi remote. I have been playing around trying to send commands to it with python. I found code on github that does most of what I need. It looks like the device itself doesn't learn any remote codes. It is all in the app. The code I found can send codes to the device and get codes from learning mode.</div>
<div dir="ltr">
I have a bunch of buttons programmed in the app already. I wanted to see if I could get those codes. I think I got them today. The app, called eControls, allows you to backup your setup. Today I was able to get my backup file from their backup site.</div>
<div dir="ltr">
Tomorrow I will try to use the codes from the backup.</div>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-16124866842960617132016-11-05T19:18:00.001-06:002017-08-11T15:21:41.128-06:00Getting Hidden App Data From Your Google DriveSome Android applications use space on your Google Drive to store data. You can't see this data by browsing drive the normal way. You can get access to it if you get the access token from the app and do a few other things. <br />
<br />
I use an app to keep some notes and other things. They require getting the paid version of the app to backup your data. I wanted to see if I could get it myself without paying for the app. I found out how to do this from this Stackoverflow post <a href="http://stackoverflow.com/questions/22832104/see-hidden-app-data-in-google-drive">http://stackoverflow.com/questions/22832104/see-hidden-app-data-in-google-drive</a>. The example there uses php. Since I have been learning Python recently, I decided to see if I could do the same thing with Python.<br />
<br />
There is a pretty good explanation of why you need to go through all the steps you need to go through to get your data in the accepted answer for that post, so I won't go into too much detail about that here.<br />
<br />
<br />
<a name='more'></a><br />
<br />
<br />
The first thing I did was get the apk for the app that I wanted the data from. I tried a couple sites that let you download the apk for an app, but they didn't seem to work. I ended up using ES File Explorer to create a backup of the app. Then I copied it over to my PC using an SD card. Then I followed the instructions in the Stackoverflow post to get the access token.<br />
<br />
The next thing that you need is a master token using your google username and password.<br />
<br />
<br />
<script src="https://gist.github.com/mattdyer/452a5b28e54c8f50876153d139774acc.js"></script>
Just remember to replace YOURUSERNAME and YOURPASSWORD with your google account credentials.<br />
<br />
Then you need to get an access token for the services you want to access. [Edit 8/11/2017 This script was missing from the article]<br />
<br />
<script src="https://gist.github.com/mattdyer/987415588cd9f381c7de8842a359f2d8.js"></script>
Replace YOURMASTERTOKEN with the value from the first script. Replace YOURAPPIDENTIFIER with the identifier for the app you are getting data for. Replace YOURAPPSIGNATURE with the SHA-1 value using the instructions in the Stackoverflow post. I removed all the colon characters and changed all the letters to lowercase to get this to work.<br />
<br />
Before the next part you will need to install the Google python library like this.<br />
<br />
<pre class="devsite-click-to-copy terminal" style="background: rgb(247, 247, 247); box-sizing: inherit; color: #37474f; font-family: "Roboto Mono", monospace; font-size: 14px; font-stretch: normal; line-height: 20px; margin-bottom: 16px; margin-top: 16px; overflow-x: auto; padding: 8px;"><code style="background: 0px center; box-sizing: inherit; font-family: "Roboto Mono", monospace; font-stretch: normal; line-height: 1; padding: 0px; word-break: normal;">pip install --upgrade google-api-python-client</code></pre>
Then you can run the following script to download files stored by the app.<br />
<br />
<br />
<script src="https://gist.github.com/mattdyer/5627a803a0355bbfe1240b0af9cea7b9.js"></script>
This script comes mainly from this page <a href="https://developers.google.com/drive/v3/web/quickstart/python">https://developers.google.com/drive/v3/web/quickstart/python</a> I just modified it a bit to download the files and skip getting the credentials because I have that already from the other 2 scripts above.<br />
<br />
This script requires creating the following json file in the same folder as the script. It needs to be named credentials.json.<br />
<br />
<br />
<script src="https://gist.github.com/mattdyer/09b80f78a5291943a65aa4d742b005c6.js"></script>
In the json file just fill in YOURACCESSTOKEN and YOURAPPSIGNATURE. The other values can be left alone. You might also have to update the token_expiry, depending on when you are reading this.<br />
<br />
I'm going to try to wrap all this up into a single script, but we'll see if I end up having time for that.<br />
<br />Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-36153044786599084892016-08-02T21:16:00.001-06:002017-03-05T21:49:19.175-07:00More Python - From web servers to machine learning<div dir="ltr">
I have an idea for building something with python that uses machine learning. It also involves the web. I have been working towards getting this all to work.</div>
<div dir="ltr">
I started with the machine learning parts. I am using the scikit learn library. I have also looked into the tensor flow library that Google made. I decided to stay with scikit learn for now. It looks like you can transition pretty easily if it turns out I need to.</div>
<div dir="ltr">
To test some parts of my idea I needed a web server. I created one in python. It took a bit of reading and several iterations before I got something that I liked. It is now setup so that it will serve any files in a folder or allow me to do things with any custom urls that I want.</div>
<div dir="ltr">
I'll try to post more about this soon. Maybe I'll post some code. Probably not. I never have time for that anymore.</div>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-58213735269621840852016-06-23T16:40:00.001-06:002017-03-05T21:49:45.491-07:00Learning python<div dir="ltr">
I've started learning python. I started looking into it because we may be doing some things with it at work if we move away from coldfusion.</div>
<div dir="ltr">
In a previous post I mentioned the Unity3d terrain editor and the ability to import and export the terrain height data. I decided to try to create one of those height map images using python. I found a Perlin noise library for python and started working on it. I haven't quite got it right yet, but I was able to generate a file that can be imported.</div>
<div dir="ltr">
I will try to post more about this with some actual code when I get it working.</div>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-172009466240091432016-04-22T15:02:00.001-06:002017-03-05T21:49:56.823-07:00Unity 3d terrain<div dir="ltr">
I started a new 3d unity project to play around with terrain creation. You can add a terrain object and then they have tools for raising and lowering the ground. There are also tools for changing textures and quickly adding trees.</div>
<div dir="ltr">
You can also import and expory the terrain height data. I am thinking it would be cool to use random noise, which I have posted about before, to generate this height data.</div>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-85833613565078168532016-04-05T13:56:00.001-06:002016-04-07T20:01:32.901-06:00Continuing with Unity<p dir="ltr">I came up with an idea for a simple game using mostly the sample assets.  I created a red crate using the pink crate.  Then I made a prefab called a finish zone.  Pushing the red crate into the finish zone gets you to the next level.<br></p>
<p dir="ltr">I made a couple other robots that walk back and forth between barriers or edges. One is blue and doesn't hurt you. The other one is red and kills you if you touch it.</p>
<p dir="ltr">With those pieces I made a few levels. I'm thinking of changing the graphics and turning it into a kids game.</p>
<p dir="ltr">It is pretty cool how simple it is to get a complete game. I also made a simple menu. One thing I haven't figured out yet is a nice way to size the controls and menu items for different screens.<br>
</p>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-72855445561466392072016-03-26T21:26:00.001-06:002016-03-26T21:31:14.220-06:00Unity 3d 2d project<p dir="ltr">I continued working on my 2d project today. I was able to get some other npc characters to animate. I added one of the pre-made killzone objects to them so if my character touches them the game restarts. </p>
<p dir="ltr">I was also able to add mobile controls and build an apk and play it on my phone. It is really hard to play with the pre-made controls and default settings. The character moves really fast. It has all been very easy to do so far.</p>
<p dir="ltr">I watched part of a video about sprites and animators to help get started.</p>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com1tag:blogger.com,1999:blog-7629438218038733260.post-84067764187792217242016-03-24T22:58:00.001-06:002016-03-24T22:58:05.661-06:00Unity 3d exploration<p dir="ltr">I tried playing around with Unity 3d today. This was the second time I have played with it. Last time I made a 3d project and played around with some of the assets we have. It was pretty cool and pretty easy to get a car setup that I could drive around. </p>
<p dir="ltr">This time I tried a 2d project. It was even easier. They have some sample assets that let you build a game with a little robot guy that can jump on platforms. I will hopefully be able to create a whole game sometime.</p>
<p dir="ltr">Maybe someday I'll actually finish one of these things I keep posting about. </p>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-35359603001087539142016-03-23T14:08:00.001-06:002016-03-23T14:08:11.078-06:00Progress on Replacing iAds with AdmobI was able to get the first app working with Admob. It was like I mentioned in the previous post, I had to create the adunit in code. I was able to find a simple example on Stack Overflow and mostly just use it as is. I had to create a header file to go along with the example file that was provided and then call that in my viewDidSomethingSomething function. I don't have it open right now so I can't remember what that is called.<br />
<br />
I had it all in place and everything would build and run, but then I was getting an exception. It turned out I had messed something up by trying to drag things around in some area of XCode where you can graphically see your app. I reverted a mainwindow.xib file back to what I had started with and everything started working.<br />
<br />
I have to do a little more testing to see how it looks in the different simulators and make sure I have my adunit id correct but then I think it is finished. Then we just have to submit it and get it re-approved by Apple. That is always a fun process.Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-59848957365644088492016-03-20T09:46:00.001-06:002016-03-20T09:46:59.929-06:00Removing iAds from apps<p dir="ltr">I have several apps published on the Apple Appstore. Four of them are using iAds and that service is going to be discontinued soon. I am going to switch them all to use Admob.</p>
<p dir="ltr">I started working on the first one. It is a pretty basic game that was built for us by a contracted developer. It has been a few years since it was originally created. I don't know if it was built poorly or the recommended ways of doing things have just changed since then, but it is not built in a way that works with the basic admob examples. They suggest that your app use a storyboard and this one does not. </p>
<p dir="ltr"> It looks like I will have to create the adunit in code and add it to the view. I found a few examples of this on Stack Overflow but I haven't had time to try it yet.</p>
<p dir="ltr">I don't have the source code for 2 of the other apps yet, someone is going to send it to me, and the fourth one was built with a framework called Moai. That last one is going to take some time to get fixed. I have to setup a development environment for that framework and the framework isn't officially supported anymore from what I can tell. </p>
<p dir="ltr">I'll post more about all this soon I hope.</p>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0tag:blogger.com,1999:blog-7629438218038733260.post-21478582615615187012016-03-11T22:55:00.001-07:002016-03-11T22:55:53.940-07:00Service worker offline cache<p dir="ltr">I continued my exploration of service workers today.  I looked at offline caching mostly.  Actually a lot of my time was spent messing with some example code that seems incorrect or out of date. I'm going back to my working code now.  I'll just have to slowly modify <u>it</u> to do what I want.</p>
<p dir="ltr">My goal is to have some simple options that I can pass into my framework that would allow turning on an offline cache for a site.  This would include a list of pages and a way to specify other pages that would be dynamically cached.</p>
<p dir="ltr">Just now I had another thought.  I should think about what it would take to make an offline cache of changes to a dynamic site. Then sync those changes when you come back online.</p>
Matt Dyerhttp://www.blogger.com/profile/14867774178059940223noreply@blogger.com0