AudioLink

/* 
 * $Id: design.txt,v 1.8 2003/11/16 18:01:02 amitshah Exp $
 *
 * The design for the AudioLink software.
 *
 * Copyright (C) 2003 Amit Shah <amitshah@gmx.net>
 *
 * This file is part of AudioLink.
 *
 * AudioLink is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License, or
 * (at your option) any later version.
 *
 * AudioLink is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with AudioLink; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Authors: Amit Shah: initial design
 */


[read the readme.txt and motivation.txt files for background
information]

How is this tool supposed to work?

As I see it now, there are two modules:

1) Go through the entire collection of songs / text and populate the
   database. This is tough... Songs would generally have information
   like the album, artist, etc. stored in the headers. But for texts,
   it is going to be difficult... Manually storing info will be the
   only way to get this right.

2) A nice user interface which will present all the search options,
   and the user then searches for something. A new directory will be
   created on a successful search with some data to work on: symlinks
   to the original files will be created in this directory.


Design for code/alsearch (Module 2): 
  I want to implement the 2nd module first, since I believe it
  will keep the project going and growing. A sample database of say, 5
  songs, will be filled manually and worked on. This will give a
  result for me to see...

  The database:
       The sample database will contains fields like, "Album", "Year",
       "SongName", "Male Artist1", "Male Artist2", "Female Artist1",
       "Female Artist2", "Band", "Composer", "Lyricist", etc. ie,
       store more info than an ID3 tag (v1) stores. It will also
       contain the absolute location of the file.

       This database design does not handle the case where the user
       changes the structure of the file organization on the file
       system. For avoiding this: 
       a) We could later write a small program by which the database
          updation for the new file path would be made simple. For
          example, a SQL query to the database to replace occurences
          of /mnt/songs/new to /mnt/songs/assorted for a particular
          file set.
       b) Another option would be to regenerate the database from
          scratch, but would be more time-, CPU-, disk-access
          consuming.
       c) A program that checks for validity/availablity of each file
          in the database. If a file doesn't exist, mark it as
          non-existant. On the next update, if a file with similar
          characteristics (like file name, artist, album, etc) is
          encountered, update the path and mark it as "existing"
          again.
       d) Have an interface within the program to facilitate moving of
          files anywhere in the filesystem: This way, we can move the
          file and also update the databae: best option, but not a
          great one for the user (why will she use our interface) (what
          if she forgets using this)... To make sure the user atleast
          considers using our tool, give a nice file manager
          front-end, so that the user just does a normal drag-and-drop
          of files, and we update the databae in the background! :-)

	  [Later, we could design a dbfs, a database file system,
	  which will make handling such things easier... The file
	  system in this case will have to store extra information
	  about the file in the metadata... and depending on the file
	  type (from the magic number), specific fields in the
	  metadata would stand for particular attributes, like:
	  user_field_1 in the metadata for an MP3 would contain the
	  album name, user_field_1 for a web page would contain the
	  name of the author, etc

	  Or, have a virtual fs sitting on top of a real fs... this
	  virtual fs will behave as mentioned in the previous
	  paragraph, but query our database on each access to the
	  file's metadata that's stored in the database. This seems
	  like a better option right now.]


  The front-end:
       A very simple search interface is to be presented first: either
       command-line driven or prompt-based. To start off, a
       prompt-based interface will be used. The user starts the
       application (don't know yet if perl supports accepting text by
       prompting the user -- if it doesn't, use C and then invoke the
       perl script) and enters the search criteria as desired.

       Based on the entries the database returns, create a directory
       based on the dir_name suggested by the user. The user is given
       two options:
       a) Create dir. name with the name of the artist
       b) Create dir. name specified by the user while giving the
       search criteria.

       In this directory, create symlinks to the original files. The
       symlinks could be organized according to the hierarchy that
       exists in the original file structure, or as all entries in the
       same directory. For example, if the file layout is such:


	    /
	    |-mnt
	      |-songs
		|-English
	        |-Hindi
		  |-chalti_ka_naam_gaadi
		  |-jhumroo

	and the user wants to listen to songs sung by Kishor Kumar, we
	could have the following two alternative layouts for our new
	directory:

	  alternative layout 1:

	    /
	    |-mnt
	      |-songs
	        |-AudioLink
		| |-Kishor_Kumar
		|   |-chalti_ka_naam_gaadi
		|   | <songs here>
		|   |-jhumroo
		|   | <songs here>
		|-English
	        |-Hindi
		  |-chalti_ka_naam_gaadi
		  |-jhumroo

	  alternative layout 2:

	    /
	    |-mnt
	      |-songs
	        |-AudioLink
		| |-Kishor_Kumar
		| | <songs here>
		|-English
	        |-Hindi
		  |-chalti_ka_naam_gaadi
		  |-jhumroo

	One of these two layouts will be chosen by the user when she is
	presented with all the options at search-time.


	Ofcourse, the new path where the symlinks will be dumped is
	also configurable.

config file:
	A config file will also be maintained to store the default
	settings, for ones like mentioned above: whether to create a
	file hierarchy based on the name of the album or in the base
	directory. This will keep a set of default options, and also
	bug the user lesser each time (this is especially needed in a
	prompt-based interface). This config file will be placed in
	~/.audiolink/config. The directory is created to accomodate
	other files we might have later.

	A system-wide config file could be desirable too, if all users
	share the same database. In this case, we can update the
	schema if it has been updated in a newer version as part of
	the package upgrade process (atleast on Debian we can do
	this).

	A better option would be to add a new table in the database
	which will store AudioLink-specific data, like the schema
	version. This will help us upgrade the schema if new versions
	exist. This change can be a per-user change, so no system-wide
	config file would be necessary. Each of the scripts could then
	call a script which first checks the database schema, updates
	it if necessary and then the original script does its job.


Design for the code/alfilldb script (Module 1):
       This script is supposed to do the following:
       * add info of song files to the database
       * update the information for existing entries in the database
       * update the ID3 tags for MP3s based on the values in the
       database (also Ogg Vorbis comments).
       * there should be level of questions like 'basic', 'limited'
       and 'all'.

       The script could be run in one of several modes:

       add-only: should just add new files: can be in interactive or
       passive modes: in the interactive mode, prompts can be made to
       put in info that doesn't exist in the file tags.

       upd-only: should just update existing files with info in the
       ID3 as well as info obtained from the user (interactive mode)

       addupd: another interactive mode: Add new files as well as
       update existing ones: combination of both the above modes.


Design for the audiolink script:
       A top-level script, audiolink, which helps in the following
       ways:

       * Creation of database tables for a first-time user
       * Creation/modification of the config file
       * If we have a new database schema (detected from config file
         and new version), transparently update the schema for the
         user.
       * Invoke the alsearch/alfilldb scripts: should be flexible, in
	 that the user may not even know the existence of these
	 scripts. She should have access to all of the audiolink
	 functionality through this one script.


       1. Check if config file exists.
       2. If not, prompt the user for creating one and fill in the
          values for the most used variables (user, pass, host for the
          DB; verbose mode; prompt mode and so on.
       3. 


Design for the virtual filesystem discussed above:
       We basically want all filesystem operations like cp, mv, rm,
       etc. to go through our code, so that we can keep our database
       uptodate. An easy-to-use implementation could just involve one
       command:

       $ mount -oloop -tdbfs /home/songs /mnt/shared/songs

       This indicates that a local directory is (loopback) mounted in
       the local namespace. Any operations now done within
       /mnt/shared/songs will go through our dbfs. If a file is moved
       anywhere within /mnt/shared/songs, the database will be
       updated, and searches will always produce links/playlists to
       the right place.
