If you want to subscribe for changes to a List<T>
in C# it is very easy. All you need to do, is subclass List<T>
and implement your own event handler. This could be done as following:
using System;
using System.Collections.Generic;
namespace FEwald
{
public class MyList<T> : List<T>
{
/// <summary>
/// EventHandler which is called when items are added.
/// </summary>
public event EventHandler ItemAdded;
/// <summary>
/// EventHandler which is called when items are deleted.
/// </summary>
public event EventHandler ItemRemoved;
/// <summary>
/// Adds an item to the list.
/// </summary>
/// <param name="item"></param>
public new void Add(T item)
{
if (ItemAdded != null)
{
ItemAdded(item, EventArgs.Empty);
}
base.Add(item);
}
/// <summary>
/// Adds a range of items to the list.
/// </summary>
/// <param name="collection"></param>
public new void AddRange(IEnumerable<T> collection)
{
foreach (var item in collection)
{
Add(item);
}
}
/// <summary>
/// Removes an item from the list.
/// </summary>
/// <param name="item"></param>
public new void Remove(T item)
{
if (ItemRemoved != null)
{
ItemRemoved(item, EventArgs.Empty);
}
base.Remove(item);
}
}
}
Currently I’m updating an odoo installation from version 8 to version 9 for a customer. In this post I will give a short introduction, on how to update the installation and most common issues I observed during the update. This post ist not complete since every odoo installation is different. First of all, there is no updater or tutorial offered by the odoo company for the community edition. The company only provides support and updates for the paid enterprise licenses. Since the database structure in odoo changed in so many fields, it is almost impossible, to update the odoo database “by hand” to version 9. The other solution, OpenUpgrade is not yet ready for the current version of the ERP system and therefore also not a possible solution. Instead, I decided to upgrade the custom developed module in a fresh odoo 9 installation. As soon as it works, I install odoo 9 with a fresh database on the server and transfer (export, then import) all the data from 8 to 9. Below is a list with possible problems and the solutions I found for them.
@api.one
and @api.multi
. All the variables, like cr
, context
, etc. still exist but have slightly different names now.
sudo ln -s /usr/local/bin/nodejs /usr/bin/node
Some days ago I created a simple script just to try out some new techniques with angularJS in combination with nodeJS. The idea was to create a lunch manager where people can sign up for a specific day, that they are in for lunch at a specific time. There should be no complex signup since I was not expecting any spam or similar behavior.
I had the idea of realising this script with a minimal footprint so that it is easy to deploy and easy to run on any Linux based server. This leads to the idea of creating a one pager with most of the Javascript files hosted on a CDN and only the absolute minimum should be hosted on my server.
##Setting up the front-end
As a front-end I chose the responsive bootstrap framework from Twitter. The dynamic part should be realized with angular. The whole website is only one controller, called FoodCtrl
.
<body ng-controller="FoodCtrl as f">
angular.module('foodApp', [])
.controller('FoodCtrl', ['$http', function($http) {
var food = this;
food.alreadyIn = false;
food.pendingRequest = false;
food.name = '';
food.namesList = [];
food.signup = function(time) {
food.pendingRequest = true;
$http.post('/lunch/signup', {name: food.name, time: time})
.then(function (response) {
console.log(response);
notie.alert(1, 'Success, you\'re in for today, ' + food.name + '!', 1.5);
food.alreadyIn = true;
food.pendingRequest = false;
}, function (response) {
notie.alert(3, 'Error ' + response.status, 5);
food.pendingRequest = false;
});
};
fetch_updates($http, food, 0, false);
refetch_updates($http, food, 0);
}])
.directive('person', function() {
return {
template: '{ {n.name}}@{ {n.time}}'
};
});
ng-cloak
on any HTML tag which should be hidden at first because it contains i.e. if-expressions which are evaluated later.
Adding only ng-cloak
alone is only half of the solution because angular adds CSS tags to all elements with this directive. But since angular is loaded just before the closing body
tag, hiding of the elements is executed often too late in time. Especially, the slower the computer, the more important it is to hide these elements just from the beginning. As a workaround I chose the following approach. Just add a style in the head part which hides ng-cloak
and this style is removed later automatically by angular:
<style type="text/css">
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
</style>
function fetch_updates($http, food, errorCounter, recursive) {
console.log('fetching names...');
$http.get('/lunch/people.json')
.then(function(response) {
if(food.namesList.length < response.data.length && recursive) {
notie.alert(4, 'Someone else signed up!', 1.5);
}
food.namesList = response.data;
if (recursive) {
refetch_updates($http, food, 0);
}
},
function(response) {
notie.alert(3, 'Error while fetching other people', 2);
refetch_updates($http, food, errorCounter + 1)
});
};
function refetch_updates($http, food, errorCounter) {
if (errorCounter < 5) {
var timeout = (errorCounter + 1) * 2000;
console.log(timeout);
setTimeout(function () {
fetch_updates($http, food, errorCounter, true);
}, timeout);
}
else {
notie.confirm('Error loading data. Do you want to retry?', 'Yes', 'No', function () {
refetch_updates($http, food, 0);
});
}
}
refetch_updates
checks the errorCounter
. If it is below 5, it calls fetch_updates
after a timeout of the error count times two seconds. The method fetch_updates
calls refetch_updates
again. If the request fails more than five times, the user is asked, if he wants to continue fetching updates or not. If yes, the errorCounter
is reset to zero and the recursive call begins again. The advantage of this method is, that I didn’t have to implement any other server than the existing nodeJS express server.
##Conclusion
From the idea to the working script it took me about two hours, if I substract the setup time of nodeJS and Apache, which only serves as a proxy this time. If you want to download the whole project, you can check out my git repository.
Under Ubuntu 14, installing nodejs is relatively easy. At first one needs to to the obvious
sudo apt-get update
followed by a
sudo apt-get install nodejs
With this two easy steps you have a nodejs installation on your system which you could easily check with node -v
. If the installation was successful, this command prints the current installed nodejs version. In my case this was the version v0.10.25 which is a bit outdated but could be sufficient if you do not plan to serve files or sites over the internet. In this case you should install the latest version from nodejs.org directly because of some severe security issues with the older versions.
In my case it was not done with installing node because the directory, where nodejs was installed to nor was in the PATH
neither there was a symlink to nodejs. For some reason, some programs rely on node
, others rely on nodejs
. So the goal was to use the same program for each command and also make it available in the PATH
to access it directly.
After asking stackoverflow, I was proposed to create an alias in the .bashrc
file like this:
alias nodejs='/usr/bin/nodejs'
Git scm offers a very interesting technique, called hooks. A hook is basically a trigger which is fired after the specific event occurs. If you create a new git repository with git init
the folder .git/hooks with a couple of sample shell scripts is created. I personally use a hook to automate the deployment process of this website. After a commit is made, I automatically run a jekyll build
and then copy the newly created site to the server.
My current post-commit script looks like the following, simple but effective:
#!/bin/bash
jekyll build
scp -r _site/* user@host:/home/user/html/
rsync
. Now the scripts looks as follows:
#!/bin/bash
jekyll build
rsync --update --progress -r _site/* user@host:/home/user/html/