# Exmaples

A good example is the best teacher. Here are several typical scenarios

* [Obfuscate script](#obfuscate-script)
* [Obfuscate package](#obfuscate-package)
* [Bind to fixed machines](#bind-to-fixed-machines)
* [Work with py2exe](#work-with-py2exe)

In the following sections, assumes that Python is installed, it can be
called

```
    python
```
Pyarmor has been installed, the installed path is `/path/to/pyarmor`

```
    # If pyarmor is installed by pip, by default /path/to/pyarmor
    # would like this
    #
    #    C:/Python27/Lib/site-packages/pyarmor  (For most of Windows)
    #
    #    /usr/local/lib/python2.7/dist-packages/pyarmor (For Ubuntu)
    #
    pip install pyarmor

    # If pyarmor is cloned from github, /path/to/pyarmor would be
    #    ./pyarmor/src
    #
    git clone https://github.com/dashingsoft/pyarmor.git
```

Shell commands will shown for Unix-based systems. Windows has
analogous commands for each.

## Obfuscate script

This example shows how to obfuscate script `queens.py` which locates
in the path `examples/simple`, and distribute obfuscated script to
customer.

And how to take registration code effects after purchased one.

```
    # Change to pyarmor path
    cd /path/to/pyarmor

    # Create projects path
    mkdir -p projects

    # Use command 'init' to create a project configured as application.
    #
    # Option --type specify the project is standalone application
    #
    # Option --src specify where to find scripts, it can be absoulte path or relative path
    #
    # Option --entry specify which script is main script. It's a script filename relative to `src`
    #
    # Last argument is the project path, it will be created if not exits.
    #
    # This command create two files in the project path "projects/simple":
    #
    #   .pyarmor_config
    #   .pyarmor_capsule.zip
    #   pyarmor
    #
    #   Here "pyarmor" is a shell script, it's a simple way to call `python pyarmor.py`
    #   (In windows, the name is "pyarmor.bat")
    #
    python pyarmor.py init --type=app \
                           --src=examples/simple \
                           --entry=queens.py projects/simple

    # Change path to project path
    cd projects/simple

    # Obfuscate scripts by command build
    # This command will obfuscate all the scripts in the `examples/simple` recursively, and
    # save the obfuscated scripts and all the runtime files in the output path `dist`
    #
    ./pyarmor build

    # Check the output
    ls ./dist

    # Check obfuscate script
    cat dist/queens.py

    # Zip all the files in the output path `dist` to `simple.zip`, and copy it to customer machine
    zip simple.zip dist/*

```

Run the following command in the customer machine

```
    # In customer machine, it's not required to install Pyarmor.
    # All the required files are packaged in the zip file.
    #
    # The only limitation is that the version of Python in the customer machine should be same as
    # the version used to obfuscate scripts in the build machine.
    #
    # Unzip `simple.zip`, then run obfuscated script
    unzip simple.zip
    cd dist
    python queens.py

```

In the trial version of Pyarmor, the key used to obfuscated scripts is
fixed. In the normal version of Pyarmor, the key used to obfuscated
scripts is random. And different project has different key. After got
a registration code, generally it will be sent to you by email like
this:

```
Regcode:
XABCILAKSDKALSDKFAJFLAJFLAJFDJASDFJAJFASKDJFAJasdkfkASSDASFAFAkaisiidoa
siSILKaISO28SLFaWIwlifskalsfKKIS5
```

In order to apply registration code, open the file `license.lic` in
the pyarmor installed path by any text editor, replace the content
with the regcode only (one line, no any newline), then save it.

Because the project capsule has been generated by trial pyarmor, so it
need to be removed, and generate new one by non-trial pyarmor.

```
    # Change to pyarmor path
    #
    cd /path/to/pyarmor

    # Remove old project
    #
    rm -rf projects/simple

    # Create project again
    python pyarmor.py init --type=app \
                           --src=examples/simple \
                           --entry=queens.py projects/simple

    ...

```

## Obfuscate package

This example shows how to obfuscate package `mypkg` which locates in
the path `examples/testpkg`, and use obfuscated package in another
machine.

```
    # Change to pyarmor path
    cd /path/to/pyarmor

    # First create project with command 'init'
    #
    # This command will create a project configured as package
    #
    # Option --type specify the project is package
    #
    # Option --src specify where to find scripts, it can be absoulte path or relative path
    #
    # Option --entry specify the `__init__.py` of package
    #
    python pyarmor.py init --type=package \
                           --src=examples/testpkg/mypkg \
                           --entry=__init__.py \
                           projects/testpkg

    # Change to project path
    cd projects/testpkg

    # Obfuscate scripts by command build
    #
    # This command will obfuscate the package and generate all the runtime files.
    #
    #   The obfuscate package is saved in the path `./dist/mypkg`
    #   The runtime files are saved in the path `./dist`
    #
    ./pyarmor build

    # Check the runtime files
    ls ./dist

    # Check the obfuscated package
    ls ./dist/mypkg

    # Check obfuscate script
    cat dist/mypkg/foo.py

    # Check entry script
    #
    #   There are 2 extra line inserted at the begining of this script.
    #
    cat dist/mypkg/__init__.py

    # Zip all the files in the output path `dist` to `mypkg.zip`, and copy it to customer machine
    zip mypkg.zip dist/*

```

In customer machine, the obfuscated package will be imported from `/home/jondy/test/main.py`

```
    # The content of main.py, it will import function and variable from obfuscated package
    cat /home/jondy/test/main.py

    from mypkg import title
    from mypkg.foo import hello
    hello(title)

    # Unzip `mypkg.zip`
    unzip mypkg.zip
    ls ./dist

    # Copy all the runtime files to any python path
    cp dist/* /home/jondy/test

    # Copy package directory to any python path
    cp -a dist/mypkg /home/jondy/test

    # Run main.py
    cd /home/jondy/test
    python main.py

```

## Bind to fixed machines

This example shows how to obfuscate script `queens.py` which locates
in the path `examples/simple`, and how to bind obfuscated script to
fixed machine of different platforms.

There are there customers in different cases:

* John, obfuscated scripts should be expired on May 5, 2019, running on Ubuntu (64-bit)
* Lily, obfuscated scripts should be bind to fixed machine by serial number of hard disk, running on Windows 10 (64-bit)
* Tom,  obfuscated scripts should be bind to fixed machine by mac address, and expired on May 5, 2019, running on Raspberry Pi

First get hardware information of customer machine, run the following command in customer machine

```
    # Download a tool 'hdinfo'

    # For John
    wget http://pyarmor.dashingsoft.com/downloads/platforms/linux_x86_64/hdinfo

    # For Lily
    wget http://pyarmor.dashingsoft.com/downloads/platforms/win_amd64/hdinfo.exe

    # All the other support platforms
    #
    #     http://pyarmor.dashingsoft.com/downloads/platforms/macosx_intel/hdinfo
    #     http://pyarmor.dashingsoft.com/downloads/platforms/win32/hdinfo.exe
    #     http://pyarmor.dashingsoft.com/downloads/platforms/linux_i386/hdinfo

    # For Tom, the platform is not supported, use the other way described below

    # Run hdinfo, it will print hardware information.
    ./hdinfo

    Serial number of first harddisk: '100304PBN2081SF3NJ5T'

    Mac address: '70:f1:a1:23:f0:94'

    Ip address: '192.168.121.101'

    Domain name: ''

```

The other way is to install a fresh pyarmor from github or pypi, then run command:

```
    python pyarmor.py hdinfo
```

The output is same as `hdinfo`. Note that a fresh pyarmor is enough to
get hardward information. DO NOT copy the pyarmor in build machine to
customer machine directly, especially `license.lic` has been replaced
with registration code of pyarmor.

In build machine,

```
    # First obfuscate scripts as the first examples
    cd /path/to/pyarmor
    python pyarmor.py init --type=app \
                           --src=examples/simple \
                           --entry=queens.py projects/simple

    cd projects/simple
    ./pyarmor build

    # Generate licenses for each customer
    #
    # For John, generate a license for a given period of time
    ./pyarmor licenses --expired 2019-03-05 john@gmail.com

    # New license saved in "licenses/john@gmail.com/license.lic"
    cat licenses/john@gmail.com/license.lic

    # Readable text saved in "licenses/john@gmail.com/license.lic.txt"
    cat licenses/john@gmail.com/license.lic.txt

    # For Lily, generate a license bind to harddisk
    ./pyarmor licenses --bind-disk '100304PBN2081SF3NJ5T' customer-lily
    ls licenses/customer-lily/license.lic

    # For Tom, generate a license bind to mac address for a given period of time
    ./pyarmor licenses --bind-mac '70:f1:a1:23:f0:94' --expired 2019-03-05 VIP-Customer
    ls licenses/VIP-customer/license.lic

    # Now make distribution package for John
    #
    # Replace `license.lic`
    cp licenses/john@gmail.com/license.lic ./dist

    # Replace platform-dependent dynamic library `_pytransform`
    rm -f dist/_pytransform.*
    wget http://pyarmor.dashingsoft.com/downloads/platforms/linux_x86_64/_pytransform.so
    mv _pytransform.so ./dist

    # Zip all files in the path `dist`, copy `myapp-for-john.zip` to John
    zip myapp-for-john.zip dist/*

    # Now make distribution package for Lily
    #
    cp licenses/customer-lily/license.lic ./dist
    rm -f dist/_pytransform.*
    wget http://pyarmor.dashingsoft.com/downloads/platforms/win_amd64/_pytransform.dll
    mv _pytransform.dll ./dist

    # Zip all files in the path `dist`, copy `myapp-for-lily.zip` to Lily
    zip myapp-for-lily.zip dist/*

    # Now make distribution package for Tom
    #
    cp licenses/VIP-customer/license.lic ./dist
    rm -f dist/_pytransform.*
    wget http://pyarmor.dashingsoft.com/downloads/platforms/raspberrypi/_pytransform.so
    mv _pytransform.so ./dist

    # Zip all files in the path `dist`, copy `myapp-for-tom.zip` to Tom
    zip myapp-for-tom.zip dist/*

```

Note that `license.lic` generated by different project is **NOT**
compatible. For example,

```
    # Create `license.lic` in another project
    cd projects/myproject
    
    # Generate `license.lic` for customer Jondy
    ./pyarmor licenses customer-jondy
    ls licenses/customer-jondy/license.lic
    
    # Copy this `license.lic` to project `simple`
    cp licenses/customer-jondy/license.lic ../../projects/simple/dist
    
    # Run obfuscated scripts in project `simple`, it will report error
    cd ../../projects/simple/dist
    python queens.py
    
```

But this is not applied to Pyarmor of trial version. The `license.lic`
generated by trial Pyarmor can be used to any project created by trial
Pyarmor.

## Work with py2exe

This example shows how to use py2exe with obfuscated scripts. Here is
a py2exe example, [py2exe/setup.py](py2exe/setup.py). It's very
simple, the entry script is [py2exe/hello.py](py2exe/hello.py), it
imports some functions from module [py2exe/queens.py](py2exe/queens.py)

The obfuscated scripts can be taken as normal python scripts, so they
can be used with any third party tools. But there are still 2
challanges with py2exe:

* All the scripts are in a zip file "library.zip"
* After scripts are obfuscated, py2exe cound not find dependent modules


```bash
    # First create project
    #
    cd /path/to/pyarmor
    python pyarmor.py init --src=examples/py2exe \
                           --entry="hello.py,setup.py" \
                           projects/py2exe
    cd projects/py2exe

    # This is the key, change default `runtime-path`. By default, pyarmor will
    # search dynamic library `_pytransform` in the same path with entry script
    # `hello.py`. When `hello.py` resides in the `library.zip`, it's failed to
    # load. By setting `runtime-path` to empty string, tell pyarmor search
    # dynamic library in the same path of `library.zip`
    #
    ./pyarmor config --runtime-path=''

    # Obfuscate scripts, after this command,
    #
    #   All the obfuscated scirpts in the path `dist`
    #   All the runtime files in the path `runtimes`
    #
    ./pyarmor build

    # First run py2exe in original package, so that all the required
    # files are generated in the "../../examples/py2exe/dist"
    #
    ( cd ../../examples/py2exe; python setup.py py2exe )

    # Run py2exe in obfuscated package with "-i" and "-p", because
    # py2exe can not find dependent modules after they're obfuscated.
    # For example, `queens.py` will be ignored if no specified by `-i`
    #
    # This command will update `../../examples/py2exe/dist/library.zip`,
    # replace those plan scripts with obfuscated scripts
    #
    # The other way is to open `library.zip` directly, then replace
    # plan scripts with obfuscated scripts manully.
    #
    ( cd dist; python setup.py py2exe -i queens -d ../../example/py2exe/dist )

    # Copy runtime files
    cp runtimes/* ../../examples/py2exe/dist

    # Now all the distributed files in the `../../examples/py2exe/dist`
    cd ../../examples/py2exe/dist
    ./hello.exe
```
