Skip to content

Source code of AuralCandy.Net - Premium House Music Podcast.

License

Notifications You must be signed in to change notification settings

teemutammela/auralcandy.net

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AuralCandy.Net - Premium House Music Podcast

This repository contains the source code of AuralCandy.Net. Please note that this application is tailored to our needs - it's not a generic, turn-key podcast platform. This source code is released for educational purposes for anyone who wishes to learn more about developing Contentful applications using Ruby and Sinatra.

This source code is distributed under Unlicense and can be used for non-commericial purposes only. Any commercial use of this source code requires explicit permission from the author. This application comes with absolutely no warranty. The author assumes no responsibility of data loss or any other unintended side-effects.

Author

Teemu Tammela

About Us

AuralCandy.Net is a House Music podcast hosted by the Finnish DJ duo MK-Ultra & Mesmic, with more than three decades of combined experience under their belt. Ever since its establishment in 2008, AuralCandy.Net podcasts have reached tens of thousands of listeners from over 150 countries. AuralCandy.Net collaborates with several prominent record labels, such as Piston Recordings and Bosh Recordings.

Table of Contents

Features

  • Technology Stack

    • Built upon the Sinatra framework
    • Utilizes Padrino stand-alone helpers
    • Content management and delivery by Contentful
    • Ready to be deployed on Heroku (tested with heroku-22 stack)
    • Includes sample data and Rack::Test tests
  • Mobile Friendly Responsive Layout

  • Episode Search

    • Search by brand and genre
    • Pagination and variable items per page
    • Sort by date, title or popularity
  • Embedded Media Player

    • Saves player state in localStorage
    • Continuous playback between page loads 1)
  • Episode Landing Pages

    • Episode description
    • Genre tags (as defined in MusicRecording schema)
    • Track listing
    • Related recording labels
    • Related episodes
  • RSS/XML Feed

  • Search Engine Optimization

  • Performance Optimization

    • Efficient use of caching, content compression and headers on the application level
    • Low amount of HTTP requests and memory footprint
    • JavaScript and SASS asset pipeline via Grunt
    • Full Cloudflare compatibility
  • Certification

1) Unless prevented by browser autoplay policy. See Media Engagement Index documentation for further details. Some browsers like Brave will require explicit permission from user to allow autoplay.

Requirements

Installation

1) Clone or fork the repository and install the required Ruby gems listed in Gemfile via Bundler.

$ git clone https://github.com/teemutammela/auralcandy.net.git
$ cd auralcandy.net
$ bundle install

2) Login to Contentful CLI and select the target space.

$ contentful login
$ contentful space use

3) Import content models to target space.

$ contentful space import --content-file import/content-models.json

4) Import example content to target space.

$ contentful space import --content-file import/example-content.json

NOTE! Tests (app/test/tests.rb) are designed to match the contents of example-content.json. Altering the example content in Contentful is likely to cause the tests to fail. It is recommended to set up two spaces or environments (e.g. production and testing) and keep the unmodified example content in the latter.

Deployment

Contentful API keys, space ID and environment must be set as environment variables. Create a new .env file by copying the example file.

$ cp .env.example .env
$ nano .env

On Heroku environment variables, also known as Config Vars, can be set either via the Dashboard or via Heroku CLI.

$ heroku config:set VARIABLE_NAME=variable_value
Variable Name Description
APPLE_PODCAST_ID Apple Podcasts ID (optional). 1)
CONTENTFUL_SPACE_ID Contentful Space ID (source of content).
CONTENTFUL_DELIVERY_KEY Contentful Delivery API key.
CONTENTFUL_MANAGEMENT_KEY Contentful Management API key.
CONTENTFUL_ENVIRONMENT Contentful environment name (e.g. master).
OP3_SHOW_UUID Open Podcast Prefix Project show UUID. 2)
OP3_API_TOKEN Open Podcast Prefix Project API token. 2)

1) If ENV["APPLE_PODCAST_ID"] is set, a apple-itunes-app meta tag will be inserted into the <head> section of the page. Read Apple's Smart App Banners documentation for further information.

2) Required by the Rake task for updating episode download count via the OP3 REST API. See section Statistic for further details.

Development (Local)

1) Start the application via the heroku local command. Application is now running at http://localhost:9292.

$ heroku local -p 9292

2) Default environment is development. Set production environment via the APP_ENV variable.

$ export APP_ENV=production

NOTE! Global variable $base_url (set in app/modules/podcast/defaults.rb) forces HTTPS in production mode. This may break some links while running the application in production mode on a local workstation. You may disable this feature by commenting the following line in app/modules/podcast/defaults.rb.

$base_url = $base_url.sub("http://", "https://") unless settings.development?

Production (Heroku)

1) Create a new Heroku application via the dashboard.

2) Login to Heroku and associate the repository with the Heroku application.

$ heroku login
$ heroku git:remote -a <APP_NAME>

3) Deploy commits to production by pushing to Heroku master repository.

$ git push heroku master

The default URL of the application is https://appname.herokuapp.com. More domains can be attached to the application via the Settings tab in the dashboard.

NOTE! Before deploying your site to public production environment, change the line Sitemap: https://www.auralcandy.net/sitemap.xml in public/robots.txt to match the domain of your production site.

Webhooks

Asset Pipeline

1) Install the required npm packages listed in package.json.

$ npm install
$ npm install -g grunt-cli

2) Launch the task runner while working with JavaScripts and stylesheets. Upon file save, *.js and *.scss files in directories /assets/javascripts/ and /assets/sass/ will be combined and compressed into target directories /public/javascripts/ and /public/stylesheets/ as configured in Gruntfile.js.

$ grunt watch

Application Structure

Configuration for development and production environments is set in app/app.rb. See Sinatra documentation for further details about configuration settings.

Directory Description
app/assets JavaScripts and SASS stylesheets.
app/classes Classes for wrapping content objects.
app/modules Contentful clients and application modules.
app/public Static files (images, compiled JavaScripts and CSS stylesheets etc.).
app/views ERB view templates and partials.

Modules

Modules are included and registered in app/app.rb. Modules follow Sinatra's standard modular extensions pattern.

Directory Module Description
app/modules/contentful delivery.rb Contentful Delivery API client.
app/modules/contentful management.rb Contentful Management API client.
app/modules/podcast defaults.rb Shared defaults (brands, genres, search form parameters and footer).
app/modules/podcast helpers.rb Generic helpers, mostly for parsing strings for various purposes.
app/modules/podcast queries.rb Query content from Contentful and wrap it to objects (registered as helpers).
app/modules/podcast routes.rb Route and URL parameter handling.

Content Models & Classes

Classes are included in app/app.rb. Classes are wrappers for corresponding Contentful content models. Classes are used for formatting field values, handling related content by wrapping them with appropriate classes, adding helper methods as object properties and defining the accessible properties of said class.

Content Model Contentful ID Class Description
Brand brand brand.rb Podcast brand 1).
DJ author dj.rb Author DJ of a podcast episode.
Episode episode episode.rb Podcast episode.
Label label label.rb Recording label related to an episode.
Navigation Anchor navigationAnchor navigation_anchor.rb Navigation menu in-page anchor.
Navigation Link navigationLink navigation_link.rb Navigation menu internal or external URL.

1) Brand content model is also used to manage site's default settings and navigation menu links and anchors. Each Brand instance can have its unique navigation menu.

Audio File Hosting

Contentful's free Community tier service package enforces a maximum asset size of 50MB, which is insufficient for podcast usage. Therefor the Episode content type is designed with external audio file hosting such as Amazon S3 in mind. Please note, that Dropbox and Google Drive are not suitable for audio file hosting, as they introduce too many redirects and latency issues.

However, if you have Team or Enterprise service package and wish to host audio files in Contentful and use the asset reference field type, simply apply the following modifications.

1) Add a file attachment field called Audio to the Episode content type.

2) Modify the @audio_url and @file_size property definitions in app/classes/episode.rb as follows.

@audio_url = entry.fields[:audio].url
@file_size = entry.fields[:audio].file.details['size']

3) Remove fields File URL and File Size from the Episode content type.

Statistics

Query episode downloads from OP3 and update the downloads properties in Contentful episode entries. Define start date as task parameter.

$ rake statistics:update_episode_downloads[YYYY-MM-DD]