Code Blog

Displaying 1-5 of 8 results.
2016/02/20 VPN

So during the recent Chinese New Year it seemed the chinese government let whatever bureau that is in charge of internet censorship to have a go at all VPN providers. I've been running PureVPN for over a year, and I must say performance has gone downhill most of the time. PureVPN mac client is also really bad, not very user-friendly at all, its just a simply tool that set up mac vpn/dialup connections (using the Mac OS builtin functionality). Anyway, just before CNY the PureVPN stopped working 100%.

I decided to try Astrill as some friends of mine use it and seems happy with it. Had much better performance than PureVPN and also much better Mac OS client (same functions as the Windows client).

However, Astrill was only working 2 days before that one also was blocked! Luckily I managed to find out via a forum post that the "Sweden 2" server for some unknown reason was still available, which made my CNY youtube watching a lot better.

Anyway, all this made me think that it may be good to look for alternative solutions. After doing some research online I decided to give Shadowsocks a try. I used to use GoAgent before, which was working great, until Google servers all got blocked by China. Shadowsocks is pretty much the same thing as GoAgent.

Shadowsocks is a lightweight socks5 proxy, written in python. It's open source, supports many encryption algorithms, it's easy to install, and can be run from many hosting providers (I'm using Amazon Web Services). 

proxy auto-config (PAC) file: defines how web browsers and other user agents can automatically choose the appropriate proxy server (access method) for fetching a given URL.
This is quite handy because you can have a PAC file that lists URLs blocked by the Chinese firewall, so you can minimize the amount of traffic going through the VPN. The ShadowSocks Windows client comes with a local PAC file, and it can also update it's PAC online from GFWList.

Shadowsocks can use the ChaCha20 cypher (a variation of the older Salsa20 cypher) which seems quite popular (a relatively new cipher with fast performance), although the default AES-256-CFB should be plenty safe as well.

The Great Firewall of China (aka Golden Shield Project) is said to perform active probing of foreign servers and block them if they host VPN services. It is therefore important that the HTTP proxy is encrypted but even this may not be enough. GoAgent used a technique called "domain fronting", a way of hiding/tunneling the traffic inside large Content Delivery Networks (CDN) that China would not like to block for economic reasons. This means a client is also needed for http-tunneling, as the web browser don't have this functionality.

Next step will be to try to run the client from a OpenWRT router.

VPNdada Shadowsocks guide
Great Firewall PAC (BASE64 encoded)
OpenWRT client
2016/02/17 Yii

Run into the following situation: The CListView in Yii dynamically loads data into its view, but the Lightbox/Slimbox and SyntaxHighlighter don't know about this change. The easiest solution I found is to attach javascript code to 'afterAjaxUpdate' for the CListView widget to run through and update the new content. I found the SyntaxHighlighter solution in a forum, but had to slightly modify it so it will autoload all possible syntaxes. I don't really like to edit the source code of the extension (as it will break at next update), but I'm not sure what the better way would be to do this.

Add this function below in the JMSyntaxHighlighter.php (JMSyntaxHighlighter extension directory)

The timeout value is a quick hack that's not very pretty. I hope there's also better ways to fix this.

function ajaxHigh(){
  SyntaxHighlighter.autoloader.apply(null, path(
   "applescript @shBrushAppleScript.js",
   "actionscript3 as3 @shBrushAS3.js",
   "bash shell @shBrushBash.js",
   "coldfusion cf @shBrushColdFusion.js",
   "cpp c @shBrushCpp.js",
   "c# c-sharp csharp @shBrushCSharp.js",
   "css @shBrushCss.js",
   "delphi pascal @shBrushDelphi.js",
   "diff patch pas @shBrushDiff.js",
   "erl erlang @shBrushErlang.js",
   "groovy @shBrushGroovy.js",
   "java @shBrushJava.js",
   "jfx javafx @shBrushJavaFX.js",
   "js jscript javascript @shBrushJScript.js",
   "perl pl @shBrushPerl.js",
   "php @shBrushPhp.js",
   "text plain @shBrushPlain.js",
   "py python @shBrushPython.js",
   "ruby rails ror rb @shBrushRuby.js",
   "sass scss @shBrushSass.js",
   "scala @shBrushScala.js",
   "sql @shBrushSql.js",
   "vb vbnet @shBrushVb.js",
   "xml xhtml xslt html @shBrushXml.js"
 setTimeout("SyntaxHighlighter.highlight();", 250);

In the view file:

$this->widget('zii.widgets.CListView', array(
   $(".viewcontent a").slimbox();

The JQuery call will match all <a href> tags within every <div class="viewcontent"> box and bind its event handler to slimbox (i'm running slimbox2.js).

On a side note this is what the official website ( of SyntaxHighlighter says about AJAX integration:

Version 3.0 is fully CommonJS compatible.

A lot of people have tried using SyntaxHighlighter with AJAX and other "non-standard" ways that I have never originally imagined it being used in. With 3.0 release, SyntaxHighlighter can just render HTML code for you completely separately from the DOM, which means that not only it plays well with AJAX, you can use it on the server side with node.jsRingoJSJaxer or any other JavaScript platform.

This sounds quite interesting but would be a quite different solution than my current Yii1 build.

2016/02/15 Yii,CSS

Wanted to update my TinyMCE editor to be able to upload images directly in the browser. So updated the TinyMCE (using the "newtinymce" extension for TinyMCE 4 and "elfinder" extension).

Some things needed changing.

The attribute is the model field that stores the text for the editor.

The "connectorRoute" default set to 'admin/elfinder/connector' made me a bit confused. I guess this means I should have an AdminController to control access for this functions. But the documentation only specified adding an ElfinderController.

The elfinder is a file manager extension to TinyMCE as it doesn't support file uploads out of the box.

I had some problems that the "file upload" got hidden behind the other popup dialog boxes. I solved it by this hack, probably not the best solution ..

elfinder.full.js in extensions/elfinder/assets/js I added:

$('.el-finder-dialog').css( { 'z-index': '10000000'} );

after the append(..).dialog(..) call in the upload function definition (line 2106 in the source file).

But the better way is to add it to the CSS file. First I had to create a CSS for the specific item's views.

To include the CSS add the code below to the view files:

$baseUrl = Yii::app()->baseUrl;
$cs = Yii::app()->getClientScript();


    z-index: 10000000;

Things left to do:

  • Compressor
  • Spellchecker

Links for Yii extensions:


I'm currently running Yii version 1.1.16 

2016/02/15 SugarCRM

My aim was to create an automatic weekly status update email for SugarCRM CE. The CE version doesn't come with this functionality built-in but it's still quite easy to create a script in PHP and add a task in Windows "task scheduler" to send out the email at a specific time and interval.

This is how I did it. First you need to create the following three files in your SugarCRM CE installation folder (relative file paths given)

  1. custom/scripts/Weeklyemail.php
  2. custom/extensions/modules/schedulers/ext/ScheduledTasks/WeeklyEmailJob.php
  3. custom/extensions/modules/schedulers/ext/ScheduledTasks/language/en_us.WeeklyEmailJob.php

The Weeklyemail.php is the part which will actually create the content for the email to be sent out. I did this by running some database queries to generate the content from the CRM database (here you may put in whatever is relevatant for your business i.e. latest Opportunities, Sales statistics etc).

SugarCRM uses the PHPMailer library for sending emails. It is an objectoriented PHP library with support for SMTP. Here's a code example in SugarCRM for creating the mail object: 

$emailobj = new Email();
$defaults = $emailobj->getSystemDefaultEmail(); 
$mail = new SugarPHPMailer();

In this setup the outgoing email is sent via the local Exchange mail server (ip address in example above, port 587 with TLS). For this to work I had to enable "extension=php_ldap.dll" in php.ini. The username and password didn't carry over correctly so I set it again explicitly in the code.

I then set up a "Scheduled task" in Windows Server 2008 r2, see screenshots below. I create a new task in "Control panel -> Administrative Tools -> Task Scheduler". The process is quite similar for any Windows system.


Need to specify the directory for php.exe process to run in, it should be the root of the SugarCRM installation, otherwise it cannot find the cron.php script file.

2016/02/15 MacOSX

I have been running into problems with my external HDD (Toshiba 1TB) when I've been in a hurry (read: too lazy) to properly eject the drive from my MacBook Air. The problem is when I plug the drive back in it just won't reappear in the finder window and even rebooting the Mac OS often won't solve the problem (it worked sometimes). This was getting rather annoying wasting a lot of time rebooting the system and still not being able to access the external HDD.
I noticed that the system has actually found the drive but did not re-attach it (mount it); I would guess this is because the OS detected a potential error and wants to protect the disk data. I found it easiest to mount the drive directly from the command line to solve this problem.

Open terminal window and run:

diskutil list

The diskutil will list all HDDs attached to your system. For my system /dev/disk0 is the internal physical drive, and /dev/disk1 is an internal virtual drive.

/dev/disk2 (external, physical):
   #:       TYPE NAME                      SIZE        IDENTIFIER
   0:       FDisk_partition_scheme         *1.0 TB     disk2
   1:       Windows_NTFS TOSHIBA EXT        1.0 TB     disk2s1

Here the diskutil listed the external HDD I want to mount with identifier /dev/disk2s1 (Windows_NTFS file partition type, filesystem is exFAT). The "s" stands for slice, which means the same thing as partition.

diskutil info /dev/disk2s1

Run the "info" option to list information about the device. It will show if it is mounted and the mount point. It also lists the filesystem used; I use exFAT for my Mac/Windows external drive.

diskutil unmount /dev/disk2s1

Here the output should be: "was already unmounted"

diskutil mount /dev/disk2s1

If output is "Volume on disk2s1 timed out waiting to mount" then try again using the "force" flag i.e. "diskutil mount force /dev/disk2s1". This used to work great for me in the past, but after recent Mac OS X updates this option seems to have been dropped from the diskutil command utility! Now I just have to wait ~5 min and after that I can mount the disk again.

On a side note "diskutil activity" may be useful to debug problems when mounting/unmounting partitions (in another terminal window). The man doc writes: "Continuously display system-wide disk manipulation activity ... This can be useful to watch system-wide activity of disks coming on-line or being ejected, volumes on disks being mounted or unmounted, volumes being renamed, etc.".

Another useful function of diskutil is the "diskutil secureErase level device" command which will zero out the entire HDD using a secure method (the "level" option selects which method to use). Save that for another time.