Main Page | Data Structures | File List | Data Fields | Globals | Related Pages

html.c

Go to the documentation of this file.
00001 /*
00002  *  html.c
00003  *  mod_musicindex
00004  *
00005  *  $Id: html.c,v 1.46 2003/10/28 20:50:11 boudinr Exp $
00006  *
00007  *  Created by Thibaut VARENE on Thu Mar 20 2003.
00008  *  Copyright (c) 2003 Regis BOUDIN
00009  *  Copyright (c) 2003 Thibaut VARENE
00010  *  
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU Lesser General Public License as published by
00013  *  the Free Software Foundation; either version 2.1, or (at your option)
00014  *  any later version.
00015  *
00016  */
00017 
00034 #include "html.h"
00035 #include "inf.h"
00036 
00043 char chaine[MAX_STRING];
00044 
00055 static char *ascii2rq(char *orig)
00056 {
00057         char *hexatable = "0123456789ABCDEF";
00058         char a;
00059         int i=0, j=0;
00060         
00061         while ((a=orig[i++]) != '\0') {
00062                 if (strchr("%;?:@&=+$<>#\"{}|\\^[]`", a)) {
00063                         chaine[j++] = '%';
00064                         chaine[j++] = hexatable[a>>4];
00065                         chaine[j++] = hexatable[a&0xf];
00066                 } else if (a == ' ') {
00067                         chaine[j++] = '+';
00068                 } else {
00069                         chaine[j++] = a;
00070                 }
00071         }
00072         chaine[j] = '\0';
00073         return chaine;
00074 }
00075 
00087 static void list_songs(request_rec * r, struct mu_ent *p, mu_config * conf)
00088 {
00089         struct mu_ent *q = p;
00090         unsigned short i = 0, j = 1;
00091         char *current = "*", *new = NULL;
00092         
00093         while (q) {
00094 
00095                 if ((conf->options & (MI_SEARCH | MI_RECURSIVE)) == (MI_SEARCH | MI_RECURSIVE)) {
00096                         new = ap_make_dirstr_parent(r->pool, q->file);
00097                 
00098                         if (strcmp(current, new)) {
00099                                 current = new;
00100                                 if ((current[0] == '\0') || (current[1] == '\0'))
00101                                         ap_rputs(" <tr class=\"title\"><th align=\"left\" colspan=\"10\">in Current Directory</th>\n", r);
00102                                 else
00103                                         ap_rvputs(r, " <tr class=\"title\"><th align=\"left\" colspan=\"10\">in <a href=\"", current, "\">", current, "</a></th>\n", NULL);
00104                                 j = 0;
00105                         }
00106                 }
00107 
00108                 if (j) {
00109                         ap_rputs(" <tr class=\"odd\">\n", r);
00110                         j = 0;
00111                 } else {
00112                         ap_rputs(" <tr class=\"even\">\n", r);
00113                         j = 1;
00114                 }
00115         
00116                 if (conf->options & (MI_ALLOWDWNLD | MI_ALLOWSTREAM)) {
00117                 
00118                         ap_rputs("  <td class=\"Select\">\n", r);
00119                 
00120                         if (conf->options & MI_ALLOWSTREAM)     /*Display [stream] */
00121                                 ap_rvputs(r, "   <input type=\"checkbox\" name=\"file\" value=\"",
00122                                         q->file, "\">\n", NULL);
00123                 
00124                 
00125                         if (conf->options & MI_ALLOWDWNLD)      /*Display [fetch] */
00126                                 ap_rvputs(r, "   <a href=\"", ap_escape_uri(r->pool, q->file), "\">"
00127                                         "<img alt=\"[F]\" src=\"", conf->fetch_icon, "\"></a>\n", NULL);
00128                 
00129                         if (conf->options & MI_ALLOWSTREAM)     /*Display [stream] */
00130                                 ap_rvputs(r, "   <a href=\"?file=", ascii2rq(q->file), "&amp;action=playlist\">"
00131                                         "<img alt=\"[S]\" src=\"", conf->sound_icon, "\"></a>\n", NULL);
00132 
00133                         ap_rputs("  </td>\n", r);
00134                 }
00135                 
00136                 for (i = 0; conf->fields[i] != '\0'; i++) {
00137                         switch (conf->fields[i]) {
00138                                 case SB_TITLE:
00139                                         ap_rvputs(r, "  <td class=\"Title\">", q->title, "</td>\n", NULL);
00140                                         break;
00141                                 case SB_TRACK:
00142                                         if (q->track)
00143                                                 ap_rprintf(r, "  <td class=\"Track\">%d</td>\n", q->track);
00144                                         else
00145                                                 ap_rputs( "  <td></td>\n", r);
00146                                         break;
00147                                 case SB_POSN:
00148                                         if (q->posn)
00149                                                 ap_rprintf(r, " <td class=\"Disc\">%d</td>\n", q->posn);
00150                                         else
00151                                                 ap_rputs( "  <td></td>\n", r);
00152                                         break;
00153                                 case SB_ARTIST:
00154                                         if (q->artist)
00155                                                 ap_rvputs(r, "  <td class=\"Artist\">", q->artist, "</td>\n", NULL);
00156                                         else
00157                                                 ap_rputs( "  <td></td>\n", r);
00158                                         break;
00159                                 case SB_LENGTH:
00160                                         if (conf->options & MI_QUICKPL)
00161                                                 break;
00162                                         if (q->length)
00163                                                 ap_rprintf(r, "  <td class=\"Duration\">%ld:%.2ld</td>\n", q->length / 60, q->length % 60);
00164                                         else
00165                                                 ap_rputs( "  <td></td>\n", r);
00166                                         break;
00167                                 case SB_BITRATE:
00168                                         if (conf->options & MI_QUICKPL)
00169                                                 break;
00170                                         if (q->bitrate)
00171                                                 ap_rprintf(r, "  <td class=\"Bitrate\">%ld</td>\n", q->bitrate >> 10);
00172                                         else
00173                                                 ap_rputs( "  <td></td>\n", r);
00174                                         break;
00175                                 case SB_DATE:
00176                                         if (q->date)
00177                                                 ap_rprintf(r, "  <td class=\"Date\">%d&nbsp</td>\n", q->date);
00178                                         else
00179                                                 ap_rputs( "  <td></td>\n", r);
00180                                         break;
00181                                 case SB_ALBUM:
00182                                         if (q->album)
00183                                                 ap_rvputs(r, "  <td class=\"Album\">", q->album, "</td>\n", NULL);
00184                                         else
00185                                                 ap_rputs( "  <td></td>\n", r);
00186                                         break;
00187                                 case SB_FILETYPE:
00188                                         switch(q->filetype) {
00189                                                 case FT_MP3:
00190                                                         ap_rvputs(r, "  <td>MP3</td>\n", NULL);
00191                                                         break;
00192                                                 case FT_OGG:
00193                                                         ap_rvputs(r, "  <td>OGG</td>\n", NULL);
00194                                                         break;
00195                                         }
00196                                         break;
00197                                 case SB_GENRE:
00198                                         if (q->genre)
00199                                                 ap_rvputs(r, "  <td class=\"Genre\">", q->genre, "</td>\n", NULL);
00200                                         else
00201                                                 ap_rputs( "  <td></td>\n", r);
00202                                         break;
00203                         }
00204                 }
00205                 ap_rputs(" </tr>\n", r);
00206                 q = q->next;
00207         }
00208 
00209 }
00210 
00222 char treat_args(request_rec * r, mu_config * conf)
00223 {
00224         const char *s = r->args;
00225         const char *p;
00226         unsigned short i;
00227 
00228         if ((s == NULL) || (*s == '\0'))
00229                 return 'A';
00230 
00231         while (s[0]){
00232                 p = ap_getword(r->pool, &s, '&');
00233                 if (!strncmp(p, "action=", 7)) {
00234                         p += 7;
00235                         if ((!strcmp(p, "playlist") || !strcmp(p, "Play+Selected")) && (conf->options & MI_ALLOWSTREAM)) {
00236                                 return 'L';
00237                         } else if ((!strcmp(p, "playall") || !strcmp(p, "Play+All")) && (conf->options & MI_ALLOWSTREAM)) {
00238                                 return 'P';
00239                         } else if (!strcmp(p, "Shuffle+All") && (conf->options & MI_ALLOWSTREAM)) {
00240                                 conf->order[0] = SB_RANDOM;
00241                                 conf->order[1] = SB_DEFAULT;
00242                                 set_fctptrs(conf);
00243                                 return 'P';
00244                         } else if (!strcmp(p, "Search") && (conf->options & MI_ALLOWSEARCH) && (conf->search[0] != '\0')) {
00245                                 conf->options |= MI_SEARCH;
00246                                 if (!conf->cache_path)
00247                                         conf->options |= MI_QUICKPL;
00248                         } else if (!strcmp(p, "Recursive+Search") && (conf->options & MI_ALLOWSEARCH) && (conf->search[0] != '\0')) {
00249                                 conf->play_recursive |= MI_SEARCH|MI_RECURSIVE;
00250                                 conf->order[0] = SB_URI;
00251                                 set_fctptrs(conf);
00252                         }
00253                                 
00254                 }
00255                 else if (!strncmp(p, "sort=", 5)) {
00256                         p += 5;
00257                         for (i = ARG_NUMBER-strlen(p)-1; i!=0; i--)
00258                                 conf->order[i] = conf->order[i-strlen(p)];
00259                         for (i=0; (i<strlen(p)) && (i<ARG_NUMBER); i++)
00260                                 conf->order[i] = p[i];
00261                         conf->order[ARG_NUMBER-1] = SB_DEFAULT;
00262                         set_fctptrs(conf);
00263                 }
00264                 else if (!strncmp(p, "option=", 7)) {
00265                         p += 7;
00266                         if (!strcmp(p, "recursive")) {
00267                                 conf->play_recursive |= MI_RECURSIVE;
00268                         }
00269                         else if (!strcmp(p, "shuffle")) {
00270                                 conf->order[0] = SB_RANDOM;
00271                                 conf->order[1] = SB_DEFAULT;
00272                                 set_fctptrs(conf);
00273                         }
00274                         else if (!strcmp(p, "quick")) {
00275                                 conf->options |= MI_QUICKPL;
00276                         }
00277                         else {
00278                                 conf->search = ap_pstrdup(r->pool, p);
00279                                 for (i=0; p[i]; i++) {
00280                                         if (p[i] == '+') {
00281                                                 conf->search[i] = ' ';
00282                                         }
00283                                 }
00284                                 ap_unescape_url(conf->search);
00285                         }
00286                 }
00287         }
00288 
00289         return 'A';
00290 }
00291 
00302 void send_url(request_rec *r, char *uri, char *command)
00303 {
00304         char *prefix = malloc(MAX_PREFIX);
00305         char str_port[6];       /* 65536 + '\0' */
00306         char *bufcoded, *decoded;
00307         unsigned short l;
00308         
00309         strcpy(prefix, "http://");
00310         
00311         if (r->connection->user) {
00312                 /* grab the auth credentials base64 encoded */
00313                 const char *auth = ap_table_get(r->headers_in, "Authorization");
00314                 if (auth) {
00315                         bufcoded = strrchr(auth, ' ');
00316                         bufcoded++;
00317                         decoded = (char *)ap_palloc(r->pool, 1 + ap_base64decode_len(bufcoded));
00318                         l = ap_base64decode(decoded, bufcoded);
00319                         decoded[l] = '\0'; /* make binary sequence into string */
00320                         strcat(prefix, decoded);        /* we have "user:pass" */
00321                 }
00322                 strcat(prefix, "@");
00323         }
00324 
00325         /* add the hostname */
00326         strcat(prefix, r->hostname);
00327         
00328         /* add the port number if needed */
00329         if (r->server->port != 80) {
00330                 sprintf(str_port, "%u", r->server->port);
00331                 strcat(prefix, ":");
00332                 strcat(prefix, str_port);
00333         }
00334         
00335         /* add the uri and potential command */
00336         ap_rvputs(r, prefix, ap_escape_uri(r->pool, uri), NULL);
00337         if (command)
00338                 ap_rvputs(r, command, NULL);
00339         ap_rvputs(r, "\n", NULL);
00340         
00341         free(prefix);
00342 }       
00343                 
00353 void send_head(request_rec * r, mu_config * conf)
00354 {
00355         char *s, *t, *u;
00356         FILE *in = NULL;
00357 
00358         s = ap_pstrdup(r->pool, r->uri);
00359 
00360         ap_rvputs(r, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n"
00361                 "<HTML>\n"
00362                 "<HEAD>\n"
00363                 " <META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"
00364                 " <link rel=\"stylesheet\" type=\"text/css\" href=\"", conf->css, "\">\n", NULL);
00365 
00366         ap_rvputs(r, " <TITLE>Musical index of ", r->uri, "</TITLE>\n"
00367                 "</HEAD>\n"
00368                 "<BODY>\n", NULL);
00369 
00370         u = s + strlen(s);
00371         if (strlen(s) > 1)
00372                 u--;
00373         if (*u == '/')
00374                 *u = '\0';
00375 
00376         ap_rputs("<table id=\"header\">\n"
00377                 " <tr>\n"
00378                 "  <td id=\"mainicon\">\n"
00379                 "   <img alt=\"Dir\" src=\"", r);
00380 
00381         if ((in = fopen(ap_pstrcat(r->pool, r->filename, "/", "cover.png", NULL), "r"))) {
00382                 ap_rputs("cover.png", r);
00383                 fclose(in);
00384         }
00385         else if ((in = fopen(ap_pstrcat(r->pool, r->filename, "/", "cover.jpg", NULL), "r"))) {
00386                 ap_rputs("cover.jpg", r);
00387                 fclose(in);
00388         }
00389         else {
00390                 ap_rputs(conf->cd_icon, r);
00391         }
00392 
00393         ap_rputs("\">\n"
00394                 "  </td>\n", r);
00395 
00396         t = u = s + 1;
00397 
00398         ap_rvputs(r, "  <td id=\"maintitle\">\n"
00399                 "    <h1>\n"
00400                 "     <a href=\"/\">", conf->title, "</a>\n", NULL);
00401 
00402         do {
00403                 while ((*u != '/') && (*u != '\0'))
00404                         u++;
00405 
00406                 if (u != s + 1)
00407                         ap_rvputs(r, "     <img src=\"", conf->arrow,
00408                                 "\" alt=\"=>\">\n", NULL);
00409 
00410                 *u = '\0';
00411                 ap_rvputs(r, "     <a href=\"", ap_escape_uri(r->pool, s), "/\">", t, "</a>\n", NULL);
00412                 *u = '/';
00413                 u++;
00414                 t = u;
00415 
00416         } while (*u != '\0');
00417 
00418         ap_rputs("    </h1>\n", r);
00419 
00420         if (conf->options & MI_ALLOWSTREAM)
00421                 ap_rputs("    <a href=\"?option=recursive&amp;option=shuffle&amp;action=playall\">"
00422                         "[Shuffle All]</a>\n"
00423                         "    <a href=\"?option=recursive&amp;action=playall\">"
00424                         "[Stream All]</a>\n", r);
00425         
00426         ap_rputs("  </td>\n", r);
00427 
00428         /* simply displays a searching box if option is activated */
00429         if (conf->options & MI_ALLOWSEARCH){
00430                 ap_rvputs(r,
00431                         "  <td id=\"search\">\n"
00432                         "   <form method=\"get\" action=\"", ap_escape_uri(r->pool, r->uri), "\""
00433                         "enctype=\"application/x-www-form-urlencoded\" name=\"searching\">\n"
00434                         "    <p>\n"
00435                         "     <input type=\"text\" name=\"option\">\n"
00436                         "     <br>\n"
00437                         "     <input type=\"hidden\" name=\"action\" value=\"Search\">\n"
00438                         "     <input type=\"submit\" name=\"action\" value=\"Search\">\n"
00439                         "     <input type=\"submit\" name=\"action\" value=\"Recursive Search\">\n"
00440                         "    </p>\n"
00441                         "   </form>\n"
00442                         "  </td>\n",
00443                         NULL);
00444         }
00445 
00446         ap_rputs(" </tr>\n"
00447                 "</table>\n"
00448                 "<hr>\n<!-- begin main -->\n\n", r);
00449 
00450 }
00451 
00463 void send_directories(request_rec * r, struct mu_ent * p, mu_config * conf)
00464 {
00465         struct mu_ent *q = p;
00466         unsigned short i = 0, nb = 0;
00467         char *c;
00468         char temp[MAX_STRING];
00469 
00470         if (!q)
00471                 return;
00472 
00473         if (q->filetype != FT_DIR)
00474                 return;
00475         
00476         /* We count the number of directories for later use */
00477         while (q && (q->filetype == FT_DIR)) {
00478                 nb++;
00479                 q = q->next;
00480         }
00481         
00482         q = p;
00483                 
00484         ap_rprintf(r, "<!-- begin subdirs -->\n<h2>Music Directories (%d)</h2>\n\n", nb);
00485 
00486         ap_rputs("<table id=\"directories\">\n", r);
00487 
00488         i = 1;
00489         while (q && (q->filetype == FT_DIR)) {
00490 
00491                 c = ap_cpystrn(temp, q->file, MAX_STRING)-1;
00492                 *c = '\0';
00493 
00494                 if (i == 1)
00495                         ap_rputs(" <tr>\n", r);
00496 
00497                 ap_rvputs(r, "  <td>\n"
00498                         "   <table>\n"
00499                         "    <tr>\n"
00500                         "     <td>\n"
00501                         "      <a href=\"", ap_escape_uri(r->pool, q->file), NULL);
00502 
00503                 if (conf->options & MI_ALLOWSTREAM)
00504                         ap_rputs("?option=recursive&amp;action=playall", r);
00505 
00506                 ap_rvputs(r, "\"><img "
00507                         "alt=\"\" "
00508                         "src=\"", conf->small_cd_icon, "\" /></a>\n"
00509                         "     </td>\n", NULL);
00510 
00511                 ap_rvputs(r, "     <td>\n"
00512                         "      <a class=\"subdir\" href=\"", ap_escape_uri(r->pool, q->file), "\">",
00513                         temp, "</a><br>\n", NULL);
00514 
00515                 if (conf->options & MI_ALLOWSTREAM) {
00516                         ap_rvputs(r, "      <a class=\"subdirbuttons\" href=\"",
00517                                 ap_escape_uri(r->pool, q->file), "?option=recursive&amp;option=shuffle&amp;option=playall\">"
00518                                 "[Shuffle]</a>\n", NULL);
00519 
00520                         ap_rvputs(r, "      <a class=\"subdirbuttons\" href=\"",
00521                                 ap_escape_uri(r->pool, q->file), "?option=recursive&amp;action=playall\">"
00522                                 "[Stream]</a>\n", NULL);
00523                 }
00524         
00525                 ap_rputs("     </td>\n"
00526                         "    </tr>\n"
00527                         "   </table>\n"
00528                         "  </td>\n",r);
00529 
00530                 if (i == 3) {
00531                         i = 0;
00532                         ap_rputs(" </tr>\n", r);
00533                 }
00534                 i++;
00535                 q = q->next;
00536         }
00537 
00538         ap_rputs("</table>\n<hr>\n<!-- end subdirs -->\n\n", r);
00539 }
00540 
00554 void send_tracks(request_rec * r, struct mu_ent *p, mu_config * conf)
00555 {
00556         struct mu_ent *q = p;
00557         unsigned short i = 0, nb = 0;
00558         char *myargs = NULL;
00559         
00560         /* We count the number of songs for later use */
00561         for (q=p; (q!=NULL); q = q->next) {
00562                 if (q->filetype != FT_DIR)
00563                         nb++;
00564         }
00565 
00566         /* Go to the first song entry (just after dirs) */
00567         q = p;
00568         while (q) {
00569                 if (q->filetype != FT_DIR)
00570                         break;
00571                 q = q->next;
00572         }
00573 
00574         if (q == NULL)
00575                 return;
00576 
00577         ap_rputs("<!-- begin tracks -->\n<h2>", r);
00578         
00579         if (conf->options & MI_SEARCH)
00580                 ap_rputs("Result", r);
00581         else
00582                 ap_rputs("Song", r);
00583         
00584         ap_rprintf(r, " List (%d)</h2>\n\n", nb);
00585 
00586         ap_rvputs(r, "<form method=\"get\" action=\"", ap_escape_uri(r->pool, r->uri), "\" "
00587                 "enctype=\"application/x-www-form-urlencoded\" name=\"form\">\n", NULL);
00588         
00589         ap_rputs("<table width=\"100%\" cellspacing=\"0\" border=\"0\">\n", r);
00590 
00591         ap_rputs(" <tr class=\"title\">\n", r);
00592         
00593         if (conf->options & (MI_ALLOWDWNLD | MI_ALLOWSTREAM))
00594                 ap_rputs("  <th id=\"Select\">Select</th>\n", r);
00595         
00596         /* XXX HACK. This is rather ugly, because if the user changes the URI by hand, he might
00597          * end up dicarding that piece of code and lead to unexpected (though not insecure)
00598          * behaviour.
00599          * The basic idea is to avoid multiple "&sort=" requests in search URI. */
00600         if (conf->options & MI_SEARCH) {
00601                 if (!(strncmp(strrchr(r->args, '&'), "&sort=", 6)))
00602                         myargs = ap_pstrndup(r->pool, r->args, strlen(r->args)-7);
00603                 else
00604                         myargs = ap_pstrdup(r->pool, r->args);
00605         }
00606         
00607         for (i = 0; conf->fields[i] != '\0'; i++) {     /* Display title line */
00608                 switch (conf->fields[i]) { 
00609                         case SB_TITLE:
00610                                 if (conf->options & MI_SEARCH)
00611                                         ap_rprintf(r, "  <th id=\"Title\"><a href=\"?%s&sort=%c\">Title<a></th>\n", myargs, SB_TITLE);
00612                                 else
00613                                         ap_rprintf(r, "  <th id=\"Title\"><a href=\"?sort=%c\">Title</a></th>\n", SB_TITLE);
00614                                 break;
00615                         case SB_TRACK:
00616                                 if (conf->options & MI_SEARCH)
00617                                         ap_rprintf(r, "  <th id=\"Track\"><a href=\"?%s&sort=%c\">Track</a></th>\n", myargs, SB_TRACK);
00618                                 else
00619                                         ap_rprintf(r, "  <th id=\"Track\"><a href=\"?sort=%c\">Track</a></th>\n", SB_TRACK);
00620                                 break;
00621                         case SB_POSN:
00622                                 if (conf->options & MI_SEARCH)
00623                                         ap_rprintf(r, "  <th id=\"Disc\"><a href=\"?%s&sort=%c\">Disc</a></th>\n", myargs, SB_POSN);
00624                                 else
00625                                         ap_rprintf(r, "  <th id=\"Disc\"><a href=\"?sort=%c\">Disc</a></th>\n", SB_POSN);
00626                                 break;
00627                         case SB_ARTIST:
00628                                 if (conf->options & MI_SEARCH)
00629                                         ap_rprintf(r, "  <th id=\"Artist\"><a href=\"?%s&sort=%c\">Artist</a></th>\n", myargs, SB_ARTIST);
00630                                 else
00631                                         ap_rprintf(r, "  <th id=\"Artist\"><a href=\"?sort=%c\">Artist</a></th>\n", SB_ARTIST);
00632                                 break;
00633                         case SB_LENGTH:
00634                                 if (!(conf->options & MI_QUICKPL)) {
00635                                         if (conf->options & MI_SEARCH)
00636                                                 ap_rprintf(r, "  <th id=\"Duration\"><a href=\"?%s&sort=%c\">Duration</a></th>\n", myargs, SB_LENGTH);
00637                                         else
00638                                                 ap_rprintf(r, "  <th id=\"Duration\"><a href=\"?sort=%c\">Duration</a></th>\n", SB_LENGTH);
00639                                 }
00640                                 break;
00641                         case SB_BITRATE:
00642                                 if (!(conf->options & MI_QUICKPL)) {
00643                                         if (conf->options & MI_SEARCH)
00644                                                 ap_rprintf(r, "  <th id=\"Bitrate\"><a href=\"?%s&sort=%c\">Bitrate</a></th>\n", myargs, SB_BITRATE);
00645                                         else
00646                                                 ap_rprintf(r, "  <th id=\"Bitrate\"><a href=\"?sort=%c\">Bitrate</a></th>\n", SB_BITRATE);
00647                                 }
00648                                 break;
00649                         case SB_ALBUM:
00650                                 if (conf->options & MI_SEARCH)
00651                                         ap_rprintf(r, "  <th id=\"Album\"><a href=\"?%s&sort=%c\">Album</a></th>\n", myargs, SB_ALBUM);
00652                                 else
00653                                         ap_rprintf(r, "  <th id=\"Album\"><a href=\"?sort=%c\">Album</a></th>\n", SB_ALBUM);
00654                                 break;
00655                         case SB_DATE:
00656                                 if (conf->options & MI_SEARCH)
00657                                         ap_rprintf(r, "  <th id=\"Date\"><a href=\"?%s&sort=%c\">Date</a></th>\n", myargs, SB_DATE);
00658                                 else
00659                                         ap_rprintf(r, "  <th id=\"Date\"><a href=\"?sort=%c\">Date</a></th>\n", SB_DATE);
00660                                 break;
00661                         case SB_FILETYPE:
00662                                 if (conf->options & MI_SEARCH)
00663                                         ap_rprintf(r, "  <th id=\"Filetype\"><a href=\"?%s&sort=%c\">Type</a></th>\n", myargs, SB_FILETYPE);
00664                                 else
00665                                         ap_rprintf(r, "  <th id=\"Filetype\"><a href=\"?sort=%c\">Type</a></th>\n", SB_FILETYPE);
00666                                 break;
00667                         case SB_GENRE:
00668                                 if (conf->options & MI_SEARCH)
00669                                         ap_rprintf(r, "  <th id=\"Genre\"><a href=\"?%s&sort=%c\">Genre</a></th>\n", myargs, SB_GENRE);
00670                                 else
00671                                         ap_rprintf(r, "  <th id=\"Genre\"><a href=\"?sort=%c\">Genre</a></th>\n", SB_GENRE);
00672                                 break;
00673                 }
00674         }
00675         ap_rputs(" </tr>\n", r);
00676 
00677         list_songs(r, q, conf);
00678         
00679         if (conf->options & MI_SEARCH)
00680                 ap_rputs("<tr class=\"title\"><th align=\"left\" colspan=\"10\">"
00681                         "<input type=\"checkbox\" name=\"all\" onClick=\"for(var i=0;i<this.form.elements.length;i++){var inpt=this.form.elements[i];"
00682                         "var m=inpt.name.match(/-/g);if((inpt.name.substr(0,4)=='file') && (m<1)) inpt.checked=this.form.all.checked}\">\n"
00683                         "Select All</th>", r);
00684                         
00685         ap_rputs("</table>\n", r);
00686 
00687         ap_rvputs(r, "<p>\n"
00688 /*              "<!--<input type=\"submit\" name=\"Add to Playlist\" value=\"Add to Playlist\" class=\"playlist\">-->"
00689                 "<!--<input type=\"submit\" name=\"Add All to Playlist\" value=\"Add All to Playlist\" class=\"playlist\">-->" */
00690                 " <input type=\"hidden\" name=\"sort\" value=\"", conf->order,"\">\n"
00691                 " <input type=\"submit\" name=\"action\" value=\"Play Selected\">\n", NULL);
00692         
00693         if (!(conf->options & MI_SEARCH))
00694                 ap_rputs(" <input type=\"submit\" name=\"action\" value=\"Shuffle All\">\n"
00695                         " <input type=\"submit\" name=\"action\" value=\"Play All\">\n", r);
00696         
00697         ap_rputs("</p>\n</form>\n<hr>\n<!-- end tracks -->\n\n", r);
00698 }
00699 
00712 void send_playlist(request_rec * r, mu_ent *p, mu_config * conf)
00713 {
00714         mu_ent *q = p;
00715         if (!p)
00716                 return;
00717 
00718         ap_rputs("#EXTM3U\n", r);
00719 
00720         while (q)
00721         {
00722                 ap_rprintf(r, "#EXTINF:%li,", q->length);
00723                 if (q->artist)
00724                         ap_rvputs(r, q->artist, " - ", NULL);
00725                 ap_rvputs(r, q->title, NULL);
00726                 if (q->album)
00727                         ap_rvputs(r, " (", q->album, ")", NULL);
00728                 ap_rvputs(r, "\n", NULL);
00729                 send_url(r, q->uri, NULL);
00730                 q = q->next;
00731         }
00732 }
00733 
00744 void send_foot(request_rec * r, mu_config * conf)
00745 {
00746         ap_rprintf(r, "<!-- end main -->\n<!-- mod_musicindex v.%s -->\n", MUSIC_VERSION_STRING);
00747         ap_rprintf(r, "<!-- Authors: %s -->\n", MUSIC_AUTHORS_STRING);
00748         ap_rputs("<table border=\"0\" width=\"100%\">\n"
00749                 " <tr>\n"
00750                 "  <td align=\"left\">\n"
00751                 "   <p>\n"
00752 #if 1
00753                 "    <a href=\"http://validator.w3.org/check/referer\">\n"
00754 #else
00755                 "    <a href=\"http://localhost/w3c-markup-validator/check/referer\">\n"
00756 #endif
00757                 "     <img src=\"http://www.w3.org/Icons/valid-html401\"\n"
00758                 "      alt=\"Valid HTML 4.01!\" height=\"31\" width=\"88\">\n"
00759                 "    </a>\n"
00760                 "   </p>\n"
00761                 "  </td>\n", r);
00762         ap_rprintf(r, "  <td align=\"right\">"
00763                 "<a href=\"http://freshmeat.net/projects/musicindex/\">"
00764                 "MusicIndex v.%s</a></td>\n", MUSIC_VERSION_STRING);
00765         ap_rputs(" </tr>\n"
00766                 "</table>\n\n</BODY>\n</HTML>", r);
00767 }

Generated on Thu Oct 30 13:50:29 2003 for mod_musicindex by doxygen 1.3.4