Monthly Archives: May 2015

NativeScript - Installation on Linux

For those just starting out on NativeScript here is what you need to get a fully running system on Linux Ubuntu 14.04 (64 bit).

The first step is to do a update and add i386 architecture to your box and then download all the compilers:

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y libncurses5:i386 libstdc++6:i386 zlib1g:i386 lib32z1 lib32ncurses5 lib32bz2-1.0 libstdc++6:i386

# Pull in all the Development stuff
sudo apt-get install -y mc linux-headers-generic build-essential g++ ant git openjdk-7-jdk p7zip p7zip-full

Next we need to download and build Node (This takes a while depending on the machine):
sudo wget -q --output-document=/usr/src/node-latest.tar.gz http://nodejs.org/dist/node-latest.tar.gz
pushd /usr/src
sudo tar zxvf node-latest.tar.gz > /dev/null
sudo chown -R $USER:$USER node-v*
cd node-v*
./configure
make
sudo make install
popd

Next we need to download and install the android SDK:
  sudo wget -q --output-document=/usr/src/android-sdk.tgz  http://dl.google.com/android/android-sdk_r24.2-linux.tgz
  pushd /usr/local
  echo Extracting Android SDK...
  sudo tar zxvf /usr/src/android-sdk.tgz > /dev/null
  sudo chown -R $USER:$USER /usr/local/android-sdk-linux
  popd

Next we are going to setup all the Paths so that some of the stuff we run later works properly:
  ANDROID_NDK_FILENAME=android-ndk-r10e
  export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
  export ANT_HOME=/usr/local/ant
  export ANDROID_HOME=/usr/local/android-sdk-linux
  export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:/usr/local/$ANDROID_NDK_FILENAME
  echo 'export ANDROID_HOME=/usr/local/android-sdk-linux' >> ~/.bashrc
  echo 'export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:/usr/local/$ANDROID_NDK_FILENAME' >> ~/.bashrc
  echo "export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64" >> ~/.bashrc
  echo "export ANT_HOME=/usr/local/ant" >> ~/.bashrc

  if [[ -f ~/.profile ]]; then
    echo 'ANDROID_HOME=/usr/local/android-sdk-linux' >> ~/.profile
    echo 'PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:/usr/local/$ANDROID_NDK_FILENAME' >> ~/.profile
    echo "export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64" >> ~/.profile
    echo "export ANT_HOME=/usr/local/ant" >> ~/.profile
  fi

  if [[ -f ~/.bash_profile ]]; then
    echo 'export ANDROID_HOME=/usr/local/android-sdk-linux' >> ~/.bash_profile
    echo 'export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:/usr/local/$ANDROID_NDK_FILENAME' >> ~/.bash_profile
    echo "export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64" >> ~/.bash_profile
    echo "export ANT_HOME=/usr/local/ant" >> ~/.bash_profile
  fi

Now we need to install all the Android SDK's, and yes we are install 17, 21, and 22.   17&21 are required for different things.  22 is for the latest sdk.
android update sdk --no-ui --filter platform-tool,android-17,android-21,android-22,build-tools-22.0.1

(OPTIONAL) Now we need install the Android NDK -- This is only needed if you are planning to build actual android runtime and metadata tool.
  ANDROID_NDK_FILENAME=android-ndk-r10e
  sudo wget -q --output-document=/usr/src/$ANDROID_NDK_FILENAME.7z http://dl.google.com/android/ndk/$ANDROID_NDK_FILENAME-linux-x86_64.bin
  sudo chmod a+r /usr/src/$ANDROID_NDK_FILENAME.7z
  sudo mkdir /usr/local/$ANDROID_NDK_FILENAME
  sudo chmod 777 /usr/local/$ANDROID_NDK_FILENAME
  7z x /usr/src/$ANDROID_NDK_FILENAME.7z -o/usr/loca

Now we need to install Grunt, and the nativescript
  sudo npm install grunt -g --unsafe-perm
  sudo npm install grunt-cli -g --unsafe-perm
  sudo npm install nativescript -g --unsafe-perm

And finally we will clone and install each of the primary NativeScript Repo's
  mkdir ~/repos
  pushd ~/repos
  git clone https://github.com/NativeScript/NativeScript
  git clone https://github.com/NativeScript/android-runtime
  git clone https://github.com/NativeScript/nativescript-cli
  git clone https://github.com/NativeScript/android-metadata-generator

  cd NativeScript
  npm install
  cd ..

  cd android-runtime
  npm install
  cd ..

  cd nativescript-cli
  npm install
  cd ..

  cd android-metadata-generator
  npm install
  cd ..

  popd

You now have everything you need to build all the components of NativeScript.   In each of the repos; you can do a grunt to build that specific repo.

NativeScript -> The new Awesome way to build Android, & IOS applications

I've been developing applications for a wide variety of platforms (you name it, I've probably touched it) .   Over my long career in computer development and devops, this includes a lot of mobile apps.    I've done hybrid apps in Phonegap/Cordova.   I've done pure native apps on the Android; and I've done apps on a Nokia Maemo/Meego, I've even done apps on old Windows Mobile 6.   So I've had some experience with a lot of mobile platforms.

So, I now have this brand new application that I have decided to write; and of course the majority of my early beta adopters will be on IOS; but the majority of my customers I believe will be on Android.  Which means, I need cross platform from the beginning.      I then spent several weeks evaluating several newer & and re-evaluating several older cross platform systems to try and decide which one to use to tackle this project in.        After most my research was done, I had narrowed it down to pretty much React Native.    Unfortunately, React Native does not have any Android bindings yet.    So, I continue looking around and while looking at Telerik's offerings, I saw a link about this all new cross platform project called NativeScript.   Figured, might as well and so I installed what was the first public release v0.9 and ...  fell in love with it.

I LOVE that it is totally cross platform for both Dev and Deployment, it runs on Mac, Linux and Windows out of the box.   And It already supports deployment to both IOS and Android, with Windows Phone bindings coming some time in the future.  Being so new it is missing a lot of things that other platforms might already have; but overall it is surprisingly feature complete.

I LOVE that it has a common library and a common screen building language that works on all the platforms; BUT it has the ability to customize them several different ways for the platform your are targeting in the event you need to make customizations per-platform. Example:

<span class="blob-code-inner"><span class="pl-s">&lt;Page&gt;&lt;TextField ios:editable='False' android:editable='True' /&gt;&lt;/Page&gt;</span></span>

As you can see, I can put in a ios: or android: prefix and have customizations for values per platform.   I can also have a file.android.xml and/or file.ios.js to make specific versions of a screen or js file per platform (there are also other valid variations for screen size/dpi).

I LOVE that I am not having to create a THUNK layer anytime I want to talk to any Android or IOS api.   NativeScript allows me to call Java code (on Android) and X Code (on IOS) functions from inside JavaScript.  Example for Android: (Java Documentaton)

var path = '/tmp/test.data';
var javaFile = new java.io.File(path);
if (!javaFile.exists()) {
  console.log("File Exists");
} else {
  console.log("File Does Not exist");
}

Do you see what I did their -- I called a native android java constructor: new java.io.File(<passed in a Javascript variable>);

I don't need to create a custom function on the android side for each time I need to do something in Android native land.  Then compile that with either the SDK or NDK and then use some sort of thunking/message layer to call it.    I can now CALL any native Java code right from my JavaScript and use the Variables and Functions as is.    (Same applies to the IOS layer)

Now the really awesome news is the entire NativeScript stack is open source.   You can download any of the pieces from github and build, create, add issues, create pull requests on any of the pieces you need to build a NativeScript IOS or Android application.

1. Cross Platform Library - This is the common library so I can do things like  var fs = require('file-system'); if (fs.exists('blah'))...  -- this code has the common and has the device specific modules so it works for every platform.
2. Android-Runtime - This is the code that has the JavaScript v8 engine on the Android Platform
3. IOS-Runtime - This is the code that runs the JavaScript Core engine on the IOS platform.
4. Android-metadata-generator - this is what creates the JavaScript bindings to the native Android Java.
5. IOS-Metadata-Generator - this is what creates the JavaScript bindings to the native IOS platform Objective-C.
6. NativeScript Command Line Interface - This is what you use to build, deploy, test your application.

Now if all you are interested in building apps; you really don't have to worry about the above repos; you just need to follow the basic install instructions for your platform at nativescript.org.

If you use VMWare or VirtualBox  or Vagrant see my next post which I will link here shortly.

 

DLNA Servers with Passwordable Folders

Over the last couple years I have played around with several DLNA servers and other media servers on my own network.      I like to eliminate the physical media and make it as simple as possible to listen to my favorite music or watch a video from anywhere in my dwelling.   Since I have kids and a wife, I need to make it simple for everyone.

However, based on my research the solutions for protected content have always been very lacking using straight DLNA.    The only solution I've seen to date using DLNA is setting up Access Groups based on the device playing the media.   However, this solution is very lacking in that their is no way to know who is actually using that device.     The only other choice I have seen is to not use DLNA, but instead use a custom front and back end to protect the content. This isn't a horrible option if the front end is available for ALL your devices.  

Up until now; neither option was a good fit for me.   So, about a month ago I figured out TWO ways to attack this problem.      The first option I really liked the best; but unfortunately after doing some research and playing with a couple DLNA clients -- I discovered not all DLNA players support searching.     So, my first idea of using the search system to allow input of password was nixed.   I needed whatever I was going to do to be fully universal and several of my devices just didn't support searching.

So my second "ingenious" idea became the actual final working implementation.    Basically, I add a new "virtual folder" (a DLNA Container Object) to the top level folders called "Password".     The rest of the folders remain the same.      In the Password folders; I put in 10 folders; labeled 0 through 9. In those folders are another 10 folders (again 0 through 9), until you have the number of digits you need.    So if you had a password of 1234, you would navigate to "Password", "1", "2", "3", "4" and then either use the "Back" or "Top" button to return to the top level.     The DLNA server, saw that you hit a 4 digits, and so it then saves this as a entered password.     Now any content that is marked with that password now actually shows up in the list of available media.  Pretty simple and a very ingenious method to allow password entries!     Their is no reason that I couldn't do 0-9 and a-z; other than it makes navigation a lot larger when you are having to scroll through 36 (or more) different options rather than a simple 10 items.

I have release my modified source code to minidlna on my own github.com account http://github.com/nathanaela/minidlna -- I will be sending a patch to the author Justin; but their are no guarantees that these changes will be accepted in the mainline as I do have a couple potential issues outlined below.

A couple notes:
You can enter as many passwords as you want; each time you enter a new password it remembers it for your entire session. This way you can actually have multiple passwords for different content.   Entering all Zeros for a password will clear all passwords you have entered during that session.   When a DLNA client disconnects from the server; the server will also forget any passwords that the client has entered for that session.   Each client has its own list of passwords; so entering the password on Device 1; does not make the content show up on any other devices.

2. New minidlna.conf configuration option:
- password_length = 1-10 (defaults to 4); this allows you to set how long you want your passwords to be.

3. New file for password configuration
You need to create a .password file in any directories you want protected.  This directory and ALL sub-directories under it will be protected then.    This is a simple text file.   At this point it is NOT encrypted or hashed.  It is raw text; so "technically" this is not very secure.  However if I already have access to the folder to read your .password file; then I can already read the media in the folder -- so you already have a insecure setup.      I would recommend you change the permissions on this file to only allow the minidlna server to read it for better security.    Again, the only content in the .password file is the password you want to use.  (ex:  echo 1111>.password would create a .password file with 1111 as the password for accessing this folder and all sub-folders).   You can also add another .password file to a sub-folder of a already password protected folder and then that sub-folder (and any of its sub-folders) would use the new password.

Gotchas:
1. Changing a password in a .password currently requires you to rebuild the database; as minidlna has to do a full scan to pick up the new password.

2. If you attempt to use a password (of a different length ie. like 123 or 12345) and have the password length set to 4; you won't be able to enter either of those as the required length is 4.

Thanks to Justin Maggard for all his hard work on minidlna, without it I wouldn't have had a base to implement the password code.