Music4U

Arthur Lisek-Koper
Derek Campaniello
December 4, 2014

Overview

Music4U provides a racket based music related search engine by utilizing various databases such as YouTube, MusicBrainz, Cover Art Archive. This program tries to solve the conventional problems of not knowing what kind of music you want to listen to or if you are just looking for something new. In order to solve these problems, Music4U will provide the user with an interactive search feature that also includes a related search feature based on the user's queries.

Screenshot

Concepts Demonstrated

  • Data abstraction is used to contain different elements of the GUI.
  • Accessors are used in order to get parsed data.
  • Accumulate (foldr) is used to parse lists of strings for formatting reasons.
  • Recursive Procedures are used in order to extract and parse XML data.
  • Lists/Trees are heavily used to store parsed data.
  • Lets/Lambdas are used in order to handle callback procedures in the GUI and are also used as local procedures.

External Technology and Libraries

  • MusicBrainz XML API
    • Provides an open source XML formatted music encyclopedia of artist, album and genre data.
  • CoverArtArchive API
    • A public domain website which provides user-submitted cover art for various albums within the MusicBrainz database.
  • Youtube Website
    • A public video sharing website.
  • net libraries (url, sendurl and head)
    • net/url is used in order to pull data from http servers (get-pure-port and get-impure-port) and converts strings to urls (string->url)
    • net/sendurl is used to open webpages in the default browser.
    • net/head is used to extract headers from an http request.
  • xml libraries (xml and path)
    • xml is used in order to read xml flat files.
    • xml/path is used to parse xml data.
  • gui library
    • gui helps create a graphical user interface using various objects and widgets.

Favorite Lines of Code

  • Arthur Lisek-Koper:
    • A class inherited from canvas% which is designed to display bitmap images and handle mouse events.

(define netimage%

  (class canvas%
    (super-new)
    (inherit get-dc)
    (init-field [bitmap-pos 0])
    (init-field [display-procedure #f])
    (init-field [clickable? #f])
    (define/override (on-event event)
      (if clickable?
          ;pop up new window with only the image
          (let ([new-event (send event button-up? 'left)])
            (if new-event
                (send (new image-window%
                           [bitmap-pos bitmap-pos])
                      show #t)
                ;else
                #f))
          ;else
          #f
          ))
    (define/override (on-paint)
      (let ([my-dc (get-dc)] [pos 0])
        (if (list? image-data)
            (if (equal? (length image-data) data-length)
                (cond ((equal? bitmap-pos 1) (send my-dc draw-bitmap (get-image (first image-data)) pos pos))
                      ((equal? bitmap-pos 2) (send my-dc draw-bitmap (get-image (first related-image-data)) pos pos))
                      (else (send my-dc draw-bitmap (read-bitmap "image-not-found.png") pos pos)))
                ;else
                (send my-dc draw-bitmap (read-bitmap "image-not-found.png") pos pos))
            ;else
            (send my-dc draw-bitmap (read-bitmap "image-not-found.png") pos pos)))))
  • Derek Campaniello:
    • This code manually parses xml data into lists or nested lists for formatting reasons.

(define (parse-data x path url type mode)

    (if (null? x) '()
      (let*
      (
       (mb-artist-url (if (equal? mode 'single)
                                  (string->url 
                                   (~a url x))
                                  (string->url
                                   (~a url (car x)))))
       (mb-artist-port (get-pure-port mb-artist-url))
       (mb-artist-response (port->string mb-artist-port))
       (mb-artist-data (xml->xexpr
                           (document-element
                            (read-xml/document (open-input-string mb-artist-response)))))
       (artist-query-tags (se-path*/list '(tag-list tag name) mb-artist-data))
       (artist-query-data (se-path* path mb-artist-data)))
        (close-input-port mb-artist-port)
        (sleep 0.05)
        (if (equal? type 'tag)
            (cons (if(null? artist-query-tags) (list "N/A") artist-query-tags) (parse-data (if (equal? mode 'single) x (cdr x)) path url type mode))
            (if (false? artist-query-data) 
                (cons "N/A" (parse-data (if (equal? mode 'single) x (cdr x)) path url type mode))
                (cons artist-query-data (parse-data (if (equal? mode 'single) x (cdr x)) path url type mode)))))))

Technology Used Block Diagram

Additional Remarks

Please use this area to include any additional information you would like to include that did not fit into any of the previous categories.