#!/bin/bash
# This script rotates the screen and touchscreen input 90 degrees each time it is called,
# also disables the touchpad, and enables the virtual keyboard accordingly
# by Ruben Barkow: https://gist.github.com/rubo77/daa262e0229f6e398766
#### configuration
# find your Touchscreen and Touchpad device with `xinput`
TouchscreenDevice='ATML1000:00 03EB:8A10'
TouchpadDevice='SYNA2B22:00 06CB:2714'
if [ "$1" = "--help" ] || [ "$1" = "-h" ] ; then
echo 'Usage: rotate-screen.sh [OPTION]'
echo
echo 'This script rotates the screen and touchscreen input 90 degrees each time it is called,'
echo 'also disables the touchpad, and enables the virtual keyboard accordingly'
echo
echo Usage:
echo ' -h --help display this help'
echo ' -j (just horizontal) rotates the screen and touchscreen input only 180 degrees'
echo ' -n always rotates the screen back to normal'
exit 0
fi
touchpadEnabled=$(xinput --list-props "$TouchpadDevice" | awk '/Device Enabled/{print $NF}')
screenMatrix=$(xinput --list-props "$TouchscreenDevice" | awk '/Coordinate Transformation Matrix/{print $5$6$7$8$9$10$11$12$NF}')
# Matrix for rotation
# ⎡ 1 0 0 ⎤
# ⎜ 0 1 0 ⎥
# ⎣ 0 0 1 ⎦
normal='1 0 0 0 1 0 0 0 1'
normal_float='1.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,1.000000'
#⎡ -1 0 1 ⎤
#⎜ 0 -1 1 ⎥
#⎣ 0 0 1 ⎦
inverted='-1 0 1 0 -1 1 0 0 1'
inverted_float='-1.000000,0.000000,1.000000,0.000000,-1.000000,1.000000,0.000000,0.000000,1.000000'
# 90° to the left
# ⎡ 0 -1 1 ⎤
# ⎜ 1 0 0 ⎥
# ⎣ 0 0 1 ⎦
left='0 -1 1 1 0 0 0 0 1'
left_float='0.000000,-1.000000,1.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000'
# 90° to the right
#⎡ 0 1 0 ⎤
#⎜ -1 0 1 ⎥
#⎣ 0 0 1 ⎦
right='0 1 0 -1 0 1 0 0 1'
if [ $screenMatrix == $normal_float ] && [ "$1" != "-n" ]
then
echo "Upside down"
xrandr -o inverted
xinput set-prop "$TouchscreenDevice" 'Coordinate Transformation Matrix' $inverted
xinput disable "$TouchpadDevice"
# Remove hashtag below if you want pop-up the virtual keyboard
#onboard &
elif [ $screenMatrix == $inverted_float ] && [ "$1" != "-j" ] && [ "$1" != "-n" ]
then
echo "90° to the left"
xrandr -o left
xinput set-prop "$TouchscreenDevice" 'Coordinate Transformation Matrix' $left
xinput disable "$TouchpadDevice"
#killall onboard
elif [ $screenMatrix == $left_float ] && [ "$1" != "-j" ] && [ "$1" != "-n" ]
then
echo "90° to the right"
xrandr -o right
xinput set-prop "$TouchscreenDevice" 'Coordinate Transformation Matrix' $right
xinput disable "$TouchpadDevice"
#killall onboard
else
echo "Back to normal"
xrandr -o normal
xinput set-prop "$TouchscreenDevice" 'Coordinate Transformation Matrix' $normal
xinput enable "$TouchpadDevice"
#killall onboard
fi
Monday, February 23, 2015
Lenovo Yoga 3 Pro rotate script for linux
Friday, July 19, 2013
Minifesto - MANIFESTO FOR MINIMALIST SOFTWARE ENGINEERS
- Fight for Pareto's law, look for the 20% of effort that will give you the 80% of results.
- Prioritize, minimalism isn't about not doing things but about focusing first in the important.
- Perfect is enemy of good, first do it, then do it right, then do it better.
- Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast.
- Add value. Think constantly how you can help your team and position yourself in that field/skill.
- Basics, first. Follow always a top-down thinking starting by the best-practises of CS.
- Think different. Simple is harder than complex, which means you'll need to use your creativity.
- Synthesis is the key of communication. We have to write code for humans not machines.
- Keep it plain. Try to keep your designs with few layers of indirection.
- Clean kipple and redundancy. Minimalism is all about removing distractions.
I am currently working on the german translation and will get the russian translation from a friend, too.
Monday, February 25, 2013
Sending stream responses with Zend Framework 2, Part 1
Sending stream responses is a new feature in Zend Framework 2.1. This short introduction will help you getting startet on how to send stream responses in Zend Framework 2.
Most times an application would deliver file downloads or video streaming with static assets, delivered directly frm Apache or Nginx. But sometimes there are restrictions: Only logged-in users should be able to download this file, watch this content, perhabs even a more complicated permission system. Then the application needs to do some permission checks and stream the response.
In this example we assume a simple file download, we deliver the file as stream response, because this is much less memory consuming and more efficient, compared to grabbing the file content and pushing it to the response body of the default response object.
namespace Application\Controller;
use Zend\Http\Headers;
use Zend\Http\Response\Stream;
use Zend\Mvc\Controller\AbstractActionController;
class IndexController extends AbstractActionController
{
public function fileAction()
{
$file = '/path/to/my/file.txt';
$response = new Stream();
$response->setStream(fopen($file, 'r'));
$response->setStatusCode(200);
$response->setStreamName(basename($file));
$headers = new Headers();
$headers->addHeaders(array(
'Content-Disposition' => 'attachment; filename="' . basename($file) .'"',
'Content-Type' => 'application/octet-stream',
'Content-Length' => filesize($file)
));
$response->setHeaders($headers);
return $response;
}
}
Even more complex use cases with download resume and speed limits are also possible in the future, but this is part of my next blog post about this topic. However you can see how easy it is to send stream responses with Zend Framework 2. As we return the response object directly in the controller, no view is created and rendered, too, so this is really a very fast operation.
Saturday, February 2, 2013
List of current php version in major linux distros
| Distribution | PHP Version |
| Ubuntu 16.04 Xenial | 7.0.4 |
| Ubuntu 15.10 Willy | 5.6.11 |
| Ubuntu 14.04 LTS Trusty | 5.5.9 |
| Ubuntu 12.04 LTS Precise | 5.3.10 |
| Ubuntu 12.10 Quantal Debian 8 Jessie |
5.4.6 5.6.14 |
| Debian 7.5 Wheezy | 5.4.4 |
| Debian 6.0.6 Squeeze | 5.3.3 |
| Cent OS 6.3 | 5.3.3 |
| Arch Linux | 5.4.11 |
| Fedora 18 | 5.4.9 |
| Fedora 17 | 5.4.1 |
| Mandriva 2011 | 5.3.20 |
| Mandriva 2010 | 5.3.2 |
| Mageia 2 | 5.3.19 |
| OpenSUSE 12.2 | 5.3.15 |
| OpenSUSE 13.1 | 5.4.20 |
| OpenSUSE 13.2 | 5.6.1 |
| Slackware 14 | 5.4.7 |
| PCLinuxOS | 5.3.8 |
| Red Hat (Enterprise) Linux 6.3 | 5.3.3 |
| Red Hat (Enterprise) Linux 7.0 RC | 5.4.16 |
| SUSE Linux Enterprise System 11 SP1 | 5.2.6 |
| SUSE Linux Enterprise System 11 SP2 | 5.2.14 |
| SUSE Linux Enterprise System 11 SP3 | 5.3.17 |
Thursday, January 10, 2013
Using git-svn for projects with many branches
We don't specify a branches section in our git configuration, instead we are attaching branches as new remotes. That also means, that we can't create or delete branches on a svn server, they have to be created with the corresponding svn commands.
svn cp1) Cloning the repository, checking out trunk/trunk /branches/ svn rm /branches/
First create a directory where you want your git repository to be on your harddrive, than initialize a new git repository.
mkdir gitsvn cd gitsvn git initNext you have to edit your git config and add the trunk as svn-remote.
edit .git/config and add:
[svn-remote "svn"]
url = http:///svn/trunk
fetch = :refs/remotes/git-svn
Next you clone the repository. This will check all SVN revisions and start a download for every revision of every file of the trunk, so this will take a while.git svn fetchYou end up with a local branch "master" that tracks the svn remote "trunk". Type "git svn info" to show information.
git svn info2) Keeping things up to date
You should never work on the master branch, that one is only reflecting the trunk, it's a mirror, so please never change files here. Just update the master to reflect the trunk, that's all.
git svn fetch git svn merge trunk –ffThe --ff flag forces a fast-forward.
3) Creating new local branches and rebase
Sometimes, you just want to create a new local branch and work on it. (Perhabs a small bugfix branch, that immediatly gets merged into trunk.)
git checkout -b bugfixbranch trunk... do some work …
git commit -m "nice explaining commit message"All unit tests are good, and you want to push that branch perhabs directory to svn trunk. But first, we need to rebase. Someone else could have made commits to trunk in the meantime, so you have to apply his changes first, than yours, that means rewriting your local history.
git svn fetch git rebase -i trunk.. now you have the choice, you can pick, reword, edit, squash and fix commits …
git svn dcommit –dry-run.. it's always recommended to make a dry-run first, so you don't push to the wrong location accidentialy
git svn dcommit4) Adding a new svn remote branch
Because we have so many branches, that git would force you to download them all, we just specify the explicit branches we want to track.
git config --add svn-remote.branchname.url http://I recommend that you specify the revision number here, otherwise git will download every revision, starting with 0 first. If your branch was created at revision 100000, you will have to wait a long time./svn/branchname git config --add svn-remote.branchname.fetch :refs/remotes/branchname git svn fetch branchname [-r ] git checkout -b localbranchname -t branchname git svn rebase branchname
git checkout -b localbranchname branchname git svn info5) Reintegrating a single commit into trunk
In the most easiest case, you have a branch with just one single commit, so you can just cherry-pick it.
git log -2Output:
commit 2db1182ddc0e85b3a9c468bd7610a58c3bb99d0a Author: sascha.prolicAs you can see, the first commit is "c56d7da69e96a662aa9aad8cd394a381bad64807", but that one is just the svn copy, we don't want to merge this, so only "2db1182ddc0e85b3a9c468bd7610a58c3bb99d0a" is interessting. Lets change to master, update, run the unit tests and commit.Date: Tue Jan 8 11:37:29 2013 +0000 Nice explaining commit message git-svn-id: http:// /svn/branches/branchname@100000 d12c8f96-4347-4129-8f7d-0f3f6588512b commit c56d7da69e96a662aa9aad8cd394a381bad64807 Author: sascha.prolic Date: Tue Jan 8 16:08:26 2013 +0000 created branch git-svn-id: http:// /svn/branches/branchname@100000 d12c8f96-4347-4129-8f7d-0f3f6588512b
git checkout master git svn fetch git merge trunk –ff git cherry-pick 2db1182ddc0e85b3a9c468bd7610a58c3bb99d0a... run unit tests
git svn dcommit
6) Reintegrate a branch into trunk
git checkout -b mergebranch branchname git svn fetch git rebase -i trunkYour editor should pop up with something like this in it:
pick 0c70bbe created new branch pick a5bf234 branchname foo pick d24360d branchname barNote, that we don't want to merge "0c70bbe", because that would was the svn cp command. Just delete this line. Save the file, and exit. You can even squash commit or edit commit messages. Run the unit tests again.
git checkout master git merge trunk –ff git merge mergebranch git svn dcommit7) Delete the branch checkout
The following command sequence will delete (locally only) the SVN branch and its history:
git branch -D local-branch git branch -D -r branch rm -rf .git/svn/branch git gcTo remove the branch on the svn server, remove it with svn rm <branchurl>.
8) Converting a local branch into a remote branch
Basically all it amounts to is a rebase, with some svn trickery.
svn cpNext you add that branch to your git config./trunk /branches/final-remote-name
git checkout local-feature-branch # This is the local branch where your prototype feature is committed. git checkout -b final-local-name # This makes the local branch derived from your local feature branch that will eventually become the branch that tracks the remote svn branch. git svn info # This will say you are following trunk. git rebase remotes/final-remote-nameVerify
git log git svn info
Friday, November 16, 2012
How to test a Zend Framework 2 Application
To run all test suites for your application, you need to install phpunit and it's dependencies, then you need to run something like this:
phpunit -c vendor/zendframework/zendframework/tests/phpunit.xml phpunit -c vendor/doctrine/common/phpunit.xml phpunit -c modules/Application/tests/phpunit.xml ...
Well, of course you can create a simple bash script, that does the job for you. But if you want to exclude disable modules, that won't work. You have to change the script each time, you disable or install a module.
The solution: Humus PHPUnit Module
Humus PHPUnit Module is a Module for Zend Framework 2 for unit testing. It is able to test all your zf2 modules and libraries at once.
The installation is quite easy:
And you DON'T have to have phpunit installed at all! HumusPHPUnitModule will install EHER/PHPUnit through composer and you have phpunit installed in your vendor directory.
Usage is easy, too:
./vendor/bin/humusphpunit
How it works:
You have two possibilities, to enable a test suite for the humus phpunit module.
1) Using HumusPHPUnitModule\ModuleManager\Feature\PHPUnitProviderInterface
<?php
namespace MyModule;
use HumusPHPUnitModule\ModuleManager\Feature\PHPUnitProviderInterface;
class Module implements PHPUnitProviderInterface
{
public function getPHPUnitXmlPaths()
{
return array(
dirname(dirname(__DIR__)) . '/tests/phpunit.xml'
);
}
}You can implement the PHPUnitProviderInterface in your own modules and provide an array of phpunit.xml files. The PHPUnit Runner collects them and runs all of them. To run the tests for thirdparty modules, that are independent from HumusPHPUnitModule, you can either write your own module, that returns phpunit.xml files for every thirdparty module you have (this can be one module per thirdparty-lib, but also a single one returning an array including all phpunit.xml files for all your thirdparty modules. Another way is using the configuration file.
2) Using configuration
<?php
return array(
'humus_phpunit_module' => array(
'phpunit_runner' => array(
'Doctrine\Common' => array(
'vendor/doctrine/common/phpunit.xml.dist'
)
)
)
);Just put this in your application configuration and run the bin script (./vendor/bin/humusphpunit).
That's all, there is also a HumusPHPUnitSampleApp - This is a demo application to show the features of Humus PHPUnit Module. It tests a sample application module with the PHPUnitListener and the Doctrine\Common lib and Zend Framework 2 with configuration.
Friday, October 12, 2012
When migration to Zend Framework 2 seems impossible
When you got a really big codebase and lots of developers working on it, releasing new features and bugfixes every 2-3 weeks, it seems impossible to migrate to Zend Framework 2, soon.
That's because you can't stop further development, you have customers waiting for the new features, they wait for bugfix releases, to get stuff running, that's buggy, you have more than 1mio lines of code and possibly > 100 active developers on that codebase. How can you migrate? I stombled accross this problem already when the first ZF2 betas came out and startet to write some code that should solve the problem.
The result is HumusMvc, it integrates Zend Framework 2's ModuleManager and ServiceManager in a ZF1 application.
The migration path
First of all, you create a new skeleton for you application. Simply clone the HumusMvcSkeletonApplication and use it as base for you skeleton app.
At the next step, you create a repository per module you have in your old ZF1 application. Put the source code in the "src/" directory of that module, create a Module.php file, name the Module, put the module configuration in it, etc. - in other words, create a simple ZF2 module out of your ZF1 application module. If you use HumusMvcAssetManager, too, you can also provide a public directory in your module and use the asset manger. That way you can override assets in a very similar way you override view scripts in a ZF1 application.
The module now can look something like this:
- MyAppDefaultModule/
- config/
- module.config.php
- layouts/
- public/
- css/
- js/
- img/
- src/
- controllers/
- models/
- views/
- tests/
- autoload_classmap.php
- composer.json
- Module.php
If you use ZF1 with the Resource-Autoloader, than you don't have psr-0 compliant classnames, so define your autoloading simply with classmap autoloader.
In order to install your module, just require it with composer.
In your module.config.php you provide your front_controller configuration, you have to tell the front controller, that you have a module, where it can dispatch.
<?php
return array(
'front_controller' => array(
'controller_directory' => array(
'default' => __DIR__ . '/../src/controllers'
),
)
);
You can now define some resources with ZF2's service manager in your module config file. You can remove those resources from bootstrapping later. HumusMvc ships with Navigation, Translator and Locale factories, so you don't need to handle these, just configure them.
If you have something like a db connection, that was bootstrapped in your old application, you need to do this again. Therefore you use the "onBootstrap" event. Well, you could define everything right now with the service manager, but that is exactly that much work, we wanted not to do now, because that would stop the further development for quite a time.
MyAppDefaultModule\Module.php
/**
* Listen to the bootstrap event
*
* @param EventInterface $e
* @return array
*/
public function onBootstrap(EventInterface $e)
{
$application = $e->getParam('application');
$serviceManager = $application->getServiceManager();
$config = $serviceManager->get('Config');
// @todo refactor later and use cleanly service manager
$this->setupDbConnection($serviceManager, $config);
// we need to put config in zend_registry
// @todo refactor later
\Zend_Registry::set('config', new \Zend_Config($config));
}
protected function setupDbConnection($serviceManager, $config)
{
if (!isset($config['myapp']['db'])) {
throw new \RuntimeException(
'No multi db config found.'
);
}
$options = $config['myapp']['db'];
if (isset($options['defaultMetadataCache'])) {
$this->setDefaultMetadataCache($options['defaultMetadataCache'], $serviceManager);
unset($options['defaultMetadataCache']);
}
$adapter = $options['adapter'];
$default = $options['default'];
unset(
$options['adapter'],
$options['default']
);
$adapter = \Zend_Db::factory($adapter, $options);
if ($default) {
\Zend_Db_Table::setDefaultAdapter($adapter);
}
}
Here is a short example you to bootstrap db connection on every request and put the application configuration into Zend_Registry.
Further refactorings
At first, I recommend to remove all "onBootstrap" methods when neccessary and put this stuff in your service manager, so you only instantiate the objects, when they are need, not on every request.
In the next refactoring rounds, you can refactor only one module at a time, so development in the other modules can still be done. Put all stuff in the service manager and use it as a service locator inside your application. Remove Zend_Registry everywhere. When you are done with that, use a php namespacer tool (or do it by manually) and refactor to a namespaced codebase. Remember, code is per module, so you can do this step module per module. Further bugfixing and development of new features is still possible.
Final migration to Zend Framework 2
You should now have a very flexible and modern Zend Framework 1 application, that makes use of a lot of stuff from Zend Framework 2, already: Service Manager, Module Manager, Event Manager, just to name a few. You don't have any expensive upfront bootstrapping any more, you moved everything to the service manger. You should have a namespaced codebase. You use ZF 2 classes much more, than ZF1 classes. - Now it's time to do the final migration.
Refactor all controllers, refactor route configuration refactor all view scripts, and so on. Now it's time for the hard work, we skipped before - but we had a couple of month time to bring our codebase to something, that _can_ be refactored to a ZF2 codebase very fast.
TouchpadDevice='SYNA2B22:00 06CB:2714'
These are the settings for my lenovo yoga 3 pro. If this is not working for you, find your Touchscreen and Touchpad device with
xinput.See also my gist at: https://gist.github.com/prolic/21673f0909c0cb5e2114