Tag Archive | howto

Pair view fields content on a Drupal 7 view quick howto

Valid for: Drupal 7, Views 3.

I have two multiple text fields on a Drupal 7 content type.

multiple fields

I want to display those fields paired by delta in a view. Here the code I used in my module named mymodule.module.

function mymodule_views_pre_render(&$view) {
  // pair field contents
  if ($view->name == 'my_view_name' && $view->current_display == 'my_view_display') {
    foreach ($view->result as $key => $res) {
      if ($res->field_data_field_youtube_url_delta != $res->field_data_field_youtube_url_description_delta) {
        unset($view->result[$key]);
      }
    }
  }
}

Thanks to hook_views_pre_render().

I use this piece of code to pair Youtube URLs and plain text description  for a JSON output generated via Views Datasource.

Remember to disallow multiple values when adding these fields to your view or you’ll get incoherent results.

Django development on Virtualbox: step by step setup

I had a bad morning trying to repair my Cygwin installation from a virtualenv mess. It’s time to get a Debian and install it on a Virtualbox for my new django project!

  • Windows: host
  • Debian: guest

Choosing the distro: what I want

  • Python 2.6
  • Django 1.4
  • Apache + Mysql

I’m a Debian fan from years so I go to the Debian website and download Wheezy netinst iso (32 bit, since I’m on a 32 bit OS and I want to use more core): wheezy met all the requirements above.

I already have a Virtualbox, so what I do is to add a new virtual disk and to add the new Wheezy netinst iso on CD/DVD images. Then I create a new Debian machine (32 bit) with two cores. I choose the iso image to be mounted on startup so the Debian setup process will start on boot.

As network device, I choose the Bridge option, so I can access the machine later from my windows host.

Installing the system

When you turn your machine on, many choices will be prompted to you. I install the webserver (apache) from the list, removed SQL server and print server and then leave desktop selected and the other default values. After some minutes Debian is installed and I can log in with the credential I have specified during installation.

Use WORKGROUP as network name if you’re running a Windows host when asked.

Install django packages

Under the Application menu, find the Debian package management tools to install what you want. As the requirements I’ve listeded above I search and install those packages:

  • python-django (1.4.1-2)
  • libapache2-mod-uwsgi
  • libapache2-mod-wsgi
  • mysql-server
  • samba

Later you can install more useful packages like virtualenv and phpmyadmin.

After you’ve installed those packages, you can do some test. Open a shell (Accessories > Terminal) and then type these commands:

What version of python I’m running?

$ python

Python 2.7.3rc2 (default, Apr 22 2012, 22:35:38)
[GCC 4.6.3] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>>

So I’ve python 2.7. Good!

>>> import django
>>> django.VERSION
(1, 4, 1, ‘final’, 0)

And I’ve Django 1.4.1.

Share your code to the Windows network (workgroup)

Now I want to read the code from one machine to another. I choose Samba server to read and write files from the virtual machine to windows and back. It will be useful since I’ve a complete Eclipse + pydev IDE on windows and I love work with it.

I open a Root terminal and type:

# ifconfig

If you choosed the Bridge network interface on installation, you will got something like this:

eth0 Link encap:Ethernet HWaddr ??????
inet addr:192.168.0.104 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: ???????????/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:49280 errors:0 dropped:0 overruns:0 frame:0
TX packets:19777 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:45400047 (43.2 MiB) TX bytes:1887849 (1.8 MiB)
Interrupt:19 Base address:0xd020

The address in bold (192.168.0.104) is the local network address of my virtual machine. If I just type this address in the Chrome browser it’s running on Windows (host) I got the “It works!” from Apache on the virtual machine. If you can’t see nothing, left click on the network icon on the bottom of your virtualbox windows > click on the menu voice and then choose the Bridge option. Then redo the ifconfig as above.

Samba tuning

Create a directory to store your django code (inside current user home folder). Open the terminal as normal user:

$ cd
$ mkdir my-django-code

Then share this folder with samba. To do this, let’s create a new user without a password:

adduser guest –home=/home/public –shell=/bin/false –disabled-password

Then add these lines to /etc/samba/smb.conf on “## Authentication ##” section:

security = share
guest_account = guest
invalid_users = root

obey pam restrictions = yes

And then after the [cdrom] commented text:

[my-django-code]
comment=Django-code
read only = no
locking = no
path = /home/myuser/my-django-code
guest ok = yes
force user = myuser

Where myuser is my (normal) user name. The lines above tell something like this to samba:

  • Let a guest user access without a password
  • …to the path /home/myuser/my-django-code
  • …”masquerading” like myuser

The “masquerade” thing is all about having the right to write files created from myuser from the guest user on the host.

When i browse my Workgroup on windows, I found the machine name I choose during installation and inside I found the my-django-code directory. I try to read and write files from the host (Windows) and from the guest (Debian) and it’s all ok.

Django, finally!

If you’re starting to develop on django, so this howto for beginners will help you a lot. Since I’ve installed the python-django package from Debian, to start a project is simple as typing this:

$ cd
$ cd my-django-code
$ django-admin startproject django_unchained
$ cd django_unchained
$ python manage.py runserver 192.168.0.104:8000

Where 192.168.0.104 is the virtual machine local network address from above and 8000 the port of the django testing webserver.

I type:

http://192.168.0.104:8000

on Crome (host: Windows) and I get the hello page from Django. Perfect!

Then, I can just follow the django howto to do the right things during the creation of my new app django_unchained!

Turn Raspberry into a small NAS with samba

I got a Raspberry Pi Model B. It’s cheap and I want to do some experiments for fun.

Experiment #1: I have a 1T external HDD (FAT) and I want to turn Raspberry into a very basic NAS.

I used:

  • 1 External USB HDD (with external power supply)
  • 1 ethernet cable CAT. 5 (10/100) or better
  • 1 HDMI cable and monitor / tv
  • 1 smartphone microusb battery charger
  • 1 SDHC (for the OS)
  • Raspbian “wheezy” (tested on 2012-08-16 release)
  • 1 modem router for connectivity (4 port)
  • 1 Windows PC plugged to the router

I flashed Raspbian into a class 10 SDHC, I follow this useful howto about to turn on HDMI instead of TV and voilà, I got a down-scaled debian system into a silent, little board that I charge with the smartphone charger via microusb (5V, 700mA).

I plug a wireless mouse and keyboard on the first USB port, and then I plug my external drive on the second. Debian read the FAT partition well (mounted on /media/MYDRIVE), but now I have to turn it into a wannabe-NAS.

Shall we dance? With Samba!

I plug the RJ-45 ethernet connector from my modem router into the Raspberry Pi and I follow this howto in Italian.

$ is a pi console (Start > Accessories > LXTerminal)
# is a root console (Start > Accessories > Root terminal)

# adduser guest --home=/home/public --shell=/bin/false --disabled-password
# sudo chmod -R 0700 /home/public
# chown -R guest.guest /home/public
$ sudo apt-get install samba smbfs

Then I have a new user “guest” with no password authentication. The howto covers the creation of a shared home (/home/public) but I do something slightly different (WORKGROUP is my local network name):

editing /etc/samba/smb.conf

## Browsing/Identification ###
# Change this to the workgroup/NT-domain name your Samba server will part of
   workgroup = WORKGROUP

####### Authentication #######
   security = share

   obey pam restrictions = yes
   guest account = guest
   invalid users = root

And now the most interesting part:

[MYDRIVE]
comment = Mydrive
read only = no
locking = no
path = /media/MYDRIVE
guest ok = yes
force user = pi

Where /media/MYDRIVE is the path to your external usb drive.

And then:

# /etc/init.d/samba restart

to apply.

As this howto explains, the “force user” allows a user (i.e. guest) to get the files from a device mounted by another user (i.e. pi, the default raspbian user).

Have fun

Now on the Windows machine on the Network panel I look for RASPBERRYPI and inside it I find the “mydrive” folder, with all the files from MYDRIVE within. I play a 720p video without slowdown. And so, the cheap NAS experiment is successfully completed.

Localize date format using i18n

Tested on:

  1. Drupal 6.16+
  2. Date API 6.x-2.4
  3. Internationalization 6.x-1.3

Any date format is stored as system variable (on the global $conf variable).

Since Internationalization module allows to declare some system variables as Multilingual, you could add to your $conf['i18n_variables'] on settings.php these lines to use different date format for different languages:

$conf['i18n_variables'] = array(
// Other variables
// bla bla bla
// Date variables
'date_format_long',
'date_format_medium',
'date_format_short',
'date_first_day',
);

date_format variables are Long, Medium and Short date format, used in many places (including Views).

date_first_day is the first day displayed on calendars (e.g. Sunday for English, Monday for Italian).

Note that you have to save the value twice via:

http://example.com/it/admin/settings/date-time

http://example.com/en/admin/settings/date-time

And one more time:

http://example.com/it/admin/settings/date-time

After the first time, you can change format as you like without double checking.

See also:

How to edit a PDF file with Open Office

Some months ago I’ve looked for a decent PDF editor for Linux. Results? Only an application called PDFedit was interesenting enought.

Now, an extension (plugin) for the cross platform suite Open Office called PDF Import do the magic with a nice PDF import for Open Office Draw.

I’ve tested it on a simple PDF document (v. 1.0.1) and the result is amazing. With Open Office, you can rewrite a PDF, save it as Draw document and export the modified version as PDF format with the handy PDF conversion tool.

Since PDF is a widely used format, you can use tool like this to download documents that require some changes before print (e.g. a paper form) without awful cut-and-paste onto an editor.

Related links:

***

Happy GNU Year to all readers, I’m glad of all of the the 100k visits of this little blog!

How to automatically translate your Drupal module

You’ve created your module. But how to translate it into different languages?

Tested with:

  • Translation template extractor 6.x-3.0
  • Drupal 6.x
  • English default + Italian translation

Prerequisites:

  • Another language active apart default (English)
  • Use t() function for all translatable string, including ones on my_funny_module.admin.inc (Administration interface).

If you use t() function correctly on your module, you can create your own translation using the handy Translation template extractor module.

  1. Download and install Translation template extractor module.
  2. Create a directory named “translations” within my_funny_module directory (your module directory)
  3. Go to admin/build/translate/extract
  4. Select your module from Directory lists
  5. Select “Language independent template” and click “Extract”
  6. Save file to my_funny_module/translations directory as my_funny_module.pot
  7. In the same screen, select “Template file for Italiano translations” (where Italiano is your destination language)
  8. If you’ve already translated some strings into Italiano language, check “Include translations” to include these strings
  9. Click “Extract”, and save file to my_funny_module/translations directory as it.po, where “it” is the ISO 639-2 code for Italiano language
  10. You can add information about translation changing the first part of both files (translator mail, name, etc.)

Now, when you install your module translation strings will be added automatically. If you apply some changes to these files, and in any case the first time you complete this procedure on an active module, you have to refresh translation cache. To do this, go to admin/build/translate/refresh and use Refresh strings and Update translations after you’ve checked all boxes. If problem persists (strings are not updated or you got some weird errors), try to reinstall your module.

Disable upload and comment for a new content type programmatically

Following code is useful when installing a module that create a new content type programmatically on Drupal 6.x.

Basically, it adds two variables setting default values for comments (core Comment module) and attachments (core Upload module).

Code to write on my_funny_module/my_funny_module.install.

function my_funny_module_install() {
  // Disable attachments
  // Read http://api.drupal.org/api/function/upload_nodeapi/6 on "load"
  variable_set("upload_my_content_type", 0);

  // Disable comments for this content type
  // Read http://api.drupal.org/api/function/comment_form_alter/6
  variable_set('comment_my_content_type', COMMENT_NODE_DISABLED);

  // Install schema as usual (if any)
  drupal_install_schema('my_funny_module');
}

Note that this code assign only default values for my_content_type: as any content type, this value could be later changed via GUI.

Theme a multiple CCK field with a table

Sometimes CCK contrib modules cannot do exactly what you want. It’s time to build your custom CCK field!

Official documentation on CCK fields creation for Drupal 6 is incomplete and some passages are obscure. If there is a good howto you have to read before do any CCK customization, this is Creating Custom CCK Fields. This howto supposes you’ve read and understand it before continue. If you want to create a custom field, you can read the complete Creating a Compound field. A custom multiple compound field (with more than one field for element, e.g. an image and its description).

Read these howto well, you’ll spare time later

Well, you have followed the howto, you have your own compound field but now you have a problem. You want to display compound field data as cells in a table, and each field as row.

On following example, we have a name list made with a multiple compound field with “firstname” and “lastname” columns.

KarenS tell you that you’ve to use CONTENT_HANDLE_MODULE instead of CONTENT_HANDLE_CORE on hook_formatter_info() .

// The machine name of the formatter.
function my_funny_module_field_formatter_info() {
  return array(
    'default' => array(
      'label' => t('Default'),
      // An array of the field types this formatter
      // can be used on.
      'field types' => array('examplefield'),
      // CONTENT_HANDLE_CORE:   CCK will pass the formatter
      // a single value.
      // CONTENT_HANDLE_MODULE: CCK will pass the formatter
      // an array of all the values. None of CCK's core
      // formatters use multiple values, that is an option
      // available to other modules that want it.
      'multiple values' => CONTENT_HANDLE_MODULE,
    ),
  );
}

/** Set the formatter **/
function my_funny_module_theme() {
  return array(
    'my_funny_module_formatter_default' => array(
      'arguments' => array('element' => NULL),
      'function' => 'funny_display_table',
    ),
  );
}

/** Here you format your table data as array **/
function my_funny_module_formatter_default($element) {
  $data = array(
      $element['#item']['firstname'],
      $element['#item']['lastname'],
  );
  return $data;
}

/** This function will display a table even where data array is empty:
 ** You have to put an additional control statement to avoid this.
 ** $element will have $data from formatter_default() above
 **/
function my_funny_module_display_table($element) {
  $header = array(
    t('First name'),
    t('Last name'),
  );
  $i = 0;
  while (!$end) {
    /** Any row will contains **/
    if(array_key_exists($i, $element)) {
      $rows[] = array(
        'firstname' => $element[$i]['#item']['firstname'],
        'lastname' =>$element[$i]['#item']['lastname'],
      );
      $i++;
    }
    else {
      $end = TRUE;
    }
  }
  /** Theme a table with data from element and header **/
  return theme('table', $header, $rows);
}

Note: to format a table you have to change only “multiple values” on my_funny_module_field_formatter_info(): you can leave my_funny_module_widget_info() as is.

See also:

Howto merge two torrent files

Update October, 2010: before trying this howto, I suggest to try mergetorrent. It’s free software, released under GNU GPL by Eyal (read comments) and it’s simpler than the method described below. Thank you Eyal!

Sometimes you want to download a torrent that you’ve partially downloaded. Many bittorrent client allow partially downloaded files, but what if you’ve downloaded the same torrent twice, with differents parts available?

Use Zeroconf / Local peer

I’ve used two client on the same LAN, ktorrent (on Debian) and utorrent (on Windows XP). I’ve two downloaded files (or folder) from the same .torrent, with different parts downloaded.

  • Enable Zeroconf plugin on ktorrent
  • Check if on utorrent “Enable local peer discovery” is enabled
  • Import existing download #1 on ktorrent
  • On debian system, as root type ifconfig to discover your local IP address, i.e.  inet addr:192.168.0.XX
  • Go to ktorrent preferences and check the used port (e.g. 12345)
  • On utorrent go to Peers tab on #2 download. Right-click > Add peer
  • Type your first machine IP address (e.g. Debian) and the first bittorrent client port (e.g. 12345 on ktorrent),  e.g. 192.168.0.XX:12345 with no protocol prepended.

On both client you’ll notice a new peer, downloading and uploading very fast. Little after, the two downloaded files / folder could be completely merged.

You can now close #2 and continue to download the torrent on a single machine / client from external peers.

Note: I’ve tested this method on the same machine using Virtualbox (Debian as host, XP as guest).

See also:

Howto extract tracks from mkv and avi

This howto requires:

  • mplayer
  • mkvtoolnix
  • your Linux box ;)

Audio from Avi files (es. Xvid + MP3):

mplayer -dumpaudio "mymovie.avi" -dumpfile mymovie_audio_track.mp3

Tracks from Matroska MKV file:

List all tracks:

mkvmerge -i mymovie.mkv

File 'mymovie.mkv': container: Matroska
Track ID 1: video (V_MS/VFW/FOURCC, XVID)
Track ID 2: audio (A_VORBIS)
Track ID 3: audio (A_VORBIS)
Track ID 4: subtitles (S_TEXT/UTF8)
Track ID 5: subtitles (S_TEXT/UTF8)

mkvextract tracks *.mkv 3:mymovie_audio_track.ogg 4:mymovie_subtitle.srt

Creates two files, mymovie_audio_track.ogg (track 3) and mymovie_subtitle.srt (track 4).

Follow

Get every new post delivered to your Inbox.

Join 27 other followers

%d bloggers like this: