I recently noticed that one of my Youtube videos was blocked worldwide due to copyright infringement. OK I must admit I don’t own the rights on this video.
What did I upload? An extract of the Malcolm TV show. How long was it? 24 seconds, not more !!! 24 tiny seconds !! What the hell? Am I really a nasty hacker or thieve? I just wanted to share a funny extract that made me laugh.
I’m pretty sure this is an automatic process using video recognition that blocked the video but still! Couldn’t it be more flexible? What’s the problem with uploading a 24s extract of a 30 minutes long video?? Would it also be chocking to post 10 pages of a 300 pages book I loved? Will Malcolm producers really loose that much money because of me? Well I think they won’t. I think what I did is good for them actually: I’ve shared something I liked and it’s been viewed 2400 times by visitors. If half of them liked the video too, won’t they also want to watch Malcolm? FREE ADVERTISING !
How could we invite friends and relatives to watch movies, to listen to music, to read books we’ve liked if we cannot share anything not even an extract. OK then, let’s play that game all together. To individuals: never talk about books, about movies, about anything because this is bad, this is theft, this is stealing artists (no kidding !!). Don’t buzz, don’t share… Let their archaic mentalities die because of their archaic system. They will have to realize one day. Hope it will not be too late for them!
PS: I hope it is not a copyright infringement to post an article about a Malcolm copyright infringement. Or could it be because of the screenshot with Hal’s face? Sorry about the Million of $ I make you loose artists !!!
Not an usual post in this blog but I just wanted to share how ridiculous advertising can be sometimes. Look how long it takes to watch a video on WAT.tv. Notice that the KIA ad runs 3 times. I hope KIA isn’t charged per view or they will receive quite a bill this month:
It’s is not only long and annoying, it is also totally ineffective, redundant and useless.
I like Safari because it is simple and fast. But Apple has added a new feature into it: the navigation sessions. When quitting Safari, your currently opened tabs and windows are saved as a navigation session… and is reopened when you start Safari again. It is very very annoying because it takes hours to start. The worse of this is that Safari has the same behavior when restarting after a crash: this is kind of stupid because it will surely open again the page that pushed Safari to the fault.
Safari seems to ignore the general system preference that allows users from preventing applications to restore their previous states on start. This setting is unchecked on my MacBook but Safari still uses the session feature. How to disable that thing then?
Open Finder and choose « Go to folder » in the app menu (or hit +shift+G). In the box, type « ~/Library/Saved Application State/ ». Locate the « com.apple.Safari.savedState » folder, highlight it. First of all, empty the folder to trash existing sessions. Then we will prevent Safari from saving sessions. Hit +i when the folder is highlighted. This will display the folder informations. Tick the « locked » checkbox. There you go: Safari will not be allowed to access this folder any longer. Sessions cannot be saved and Safari is now much quicker.
It’s been a little while that the Ananoos service exists. Very useful and easy, powerful and cheap VPN service. It works on top of OpenVPN which provides high security and encrypted connections. Besides I’m using Transmission which is a free and efficient BitTorrrent client.
The goal is to make sure the VPN connection is always up when using Transmission. When starting Transmission or when the VPN link fails, the VNP connection is restarted. And if really there is no way to get back the VPN link, the Transmission app is simple closed.
# SET HERE YOUR TUNNELBLICK
# CONNECTION NAME
# IN MY CASE: Ananoos
set VPNConnection to "Ananoos"
repeat
# If transmission is running
if appIsRunning("Transmission") then
set vpn to ""
if appIsRunning("TunnelBlick") then
# TunnelBlick is running
# Checking whether it is connected
tell application "Tunnelblick"
set vpn to get state of first configuration where name = VPNConnection
end tell
else
tell application "Tunnelblick" to activate
end if
# VPN is connected, all fine
if vpn = "CONNECTED" then
#display alert "Transmission is running and protected"
else
# VPN is not connected, forcing reconnect
tell application "Tunnelblick"
connect VPNConnection
end tell
# Waiting for reconnection
repeat 10 times
tell application "Tunnelblick"
# Is VPN connected at last?
set vpn to get state of first configuration where name = VPNConnection
# Yes, exiting loop
if vpn = "CONNECTED" then exit repeat
do shell script "sleep 3"
end tell
end repeat
# Checking whether TunnelBlick has reconnected
if vpn = "CONNECTED" then
display alert "ATTENTION: Transmission was running without VPN protection. We have successfully forced reconnection..."
else
# Not reconnected, better quit Transmission
tell application "Transmission"
quit
end tell
display alert "ATTENTION: Transmission was running unprotected. We were unable to reconnect to VPN therefore we have closed it..."
end if
end if
end if
do shell script "sleep 1"
end repeat
on appIsRunning(appName)
tell application "System Events" to (name of processes) contains appName
end appIsRunning
Open the Mac AppleScript Editor. Copy and paste the above code. Save as an application and make sure this app is automatically started on login. Attention 1: this script works only with TunnelBlick which is a openVPN Mac GUI. Ananoos offers either their own VPN client or the TunnelBlick config files. Prefer 2nd option. Attention 2: line4, I refer to the « Ananoos » connection. If your have named it differently, update the script.
I recently came to a situation where I had to check 1800 links validity. No chance to do it manually. I decided to write some PHP code to check these URLs using the PHP get_headers function. Checking an URL seems easy but it takes a tiny amount of time to process because it calls distant resources: DNS lookup, connection time, download time… for each request. Using a simple « while » PHP function, you may come across three issues:
it may be very long to complete and it’s not always possible to increase the PHP maximum execution time
the display: your web page will be blank for quite a long time until enough data is processed. Of course you may play with the buffer handler but still!
the process: as PHP is not a multi-threaded language out of the box, it will check one link by one. Much longer…
Therefore, I developed a very simple peace of code to solve these issues. As it is working quite softly, I decided to share it with you. Read the rest of this entry »
[EDIT 2013-01-14] the following code has been modified. There was a bug that would prevent some very particular attachments to be saved. Thanks to Byron for alerting me. Also attachments are now exported into a directory.
I’ve been busy working on a piece of code whose role is to extract all attachments from emails using PHP and IMAP. It is not really simple so here’s a recursive function doing that work:
<?php
// SETTINGS
$server = '{imap.vidax.net:993/imap/ssl}INBOX';
$username = 'test@vidax.net';
$password = 'test';
$export_dir = '/home/axel/test/'; # final slash is required
// END SETTINGS
$mbox = imap_open($server, $username, $password) or die('Unable to login');
// Getting all emails
if ($headers = imap_headers($mbox)) {
$i = 0;
foreach ($headers as $val) {
$i ++;
// Will return many infos about current email
// Use var_dump($info) to check content
$info = imap_headerinfo($mbox, $i);
$msgid = trim($info->Msgno);
// Gets the current email structure (including parts)
// Use var_dump($structure) to check it out
$structure = imap_fetchstructure($mbox, $msgid);
// Getting attachments
// Will return an array with all included files
// Also works with inline attachments
$attachments = get_attachments($structure);
// You are now able to get attachments' raw content
foreach ($attachments as $k => $at) {
$filename = $export_dir.'id_'.$msgid.'_part_'.str_replace('.', '-', $at['part']).'_'.$at['filename'];
$content = imap_fetchbody($mbox, $msgid, $at['part']);
if ($content !== false && strlen($content) > 0 && $content != '') {
switch ($at['encoding']) {
case '3':
$content = base64_decode($content);
break;
case '4':
$content = quoted_printable_decode($content);
break;
}
file_put_contents($filename, $content);
}
}
}
}
// Shutting down
imap_close($mbox);
/**
* Gets all attachments
* Including inline images or such
* @author: Axel de Vignon
* @param $content: the email structure
* @param $part: not to be set, used for recursivity
* @return array(type, encoding, part, filename)
*
*/
function get_attachments($content, $part = null, $skip_parts = false) {
static $results;
// First round, emptying results
if (is_null($part)) {
$results = array();
}
else {
// Removing first dot (.)
if (substr($part, 0, 1) == '.') {
$part = substr($part, 1);
}
}
// Saving the current part
$actualpart = $part;
// Split on the "."
$split = explode('.', $actualpart);
// Skipping parts
if (is_array($skip_parts)) {
foreach ($skip_parts as $p) {
// Removing a row off the array
array_splice($split, $p, 1);
}
// Rebuilding part string
$actualpart = implode('.', $split);
}
// Each time we get the RFC822 subtype, we skip
// this part.
if (strtolower($content->subtype) == 'rfc822') {
// Never used before, initializing
if (!is_array($skip_parts)) {
$skip_parts = array();
}
// Adding this part into the skip list
array_push($skip_parts, count($split));
}
// Checking ifdparameters
if (isset($content->ifdparameters) && $content->ifdparameters == 1 && isset($content->dparameters) && is_array($content->dparameters)) {
foreach ($content->dparameters as $object) {
if (isset($object->attribute) && preg_match('~filename~i', $object->attribute)) {
$results[] = array(
'type' => (isset($content->subtype)) ? $content->subtype : '',
'encoding' => $content->encoding,
'part' => empty($actualpart) ? 1 : $actualpart,
'filename' => $object->value
);
}
}
}
// Checking ifparameters
else if (isset($content->ifparameters) && $content->ifparameters == 1 && isset($content->parameters) && is_array($content->parameters)) {
foreach ($content->parameters as $object) {
if (isset($object->attribute) && preg_match('~name~i', $object->attribute)) {
$results[] = array(
'type' => (isset($content->subtype)) ? $content->subtype : '',
'encoding' => $content->encoding,
'part' => empty($actualpart) ? 1 : $actualpart,
'filename' => $object->value
);
}
}
}
// Recursivity
if (isset($content->parts) && count($content->parts) > 0) {
// Other parts into content
foreach ($content->parts as $key => $parts) {
get_attachments($parts, ($part.'.'.($key + 1)), $skip_parts);
}
}
return $results;
}
Bonus tip: you may display images using their raw content data. For instance, the following HTML code will display a red dot:
On the 25th of february 2010, I wrote a post explaining how to handle domain aliases with Postfix (http://vidax.net/blog/2010/02/domain-aliases-with-postfix/). I recently decided to add dynamic addresses support. Google uses this convenient feature. Let’s say your address is « james@domain.com ». Using the dynamic addresses, you will be able to route « james+anything@domain.com » to your real address.
When it comes to project management, Redmine is one of the best tools according to me. Written in Ruby on Rails, it offers a huge amount of features in a clean, really nice and efficient interface. Plus it’s free and open source.
One of these features is related to Subversion. Redmine is able to interact with Subversion:
it has a powerful repository browser able to link tasks and commits.
it can manage SVN authentication. Redmine users have therefore access to the SVN repository with same username and password
Sadly, this is not that simple. This tutorial doesn’t work on recent versions of Redmine (see post here: http://www.redmine.org/boards/2/topics/24383?r=26204). Redmine has updated it authentication system in adding a salt field. Initially, Redmine passwords were SHA1(password) only. Now passwords are SHA1(salt.SHA1(password)). This format is not supported by pam_mysql out of the box.
Travaillant intensément avec Subversion, j’utilise plusieurs branches pour gérer mes sites de développement et mes sites de production. Je passe donc chaque fonctionnalité d’une branche à l’autre pour les passer en PROD, ce qui correspond à un « merge » SVN.