Skip to content

Commit

Permalink
added podcast, item models to store feed items in database, updated v…
Browse files Browse the repository at this point in the history
…iew to list feed items from db, added feature to generate resized thumbnail for each podcast and store to filesystem
  • Loading branch information
Srikanth-AD committed Jun 8, 2015
1 parent b51f74b commit c436a6d
Show file tree
Hide file tree
Showing 14 changed files with 230 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
/vendor
/node_modules
.env
/public/images/*
59 changes: 45 additions & 14 deletions app/Http/Controllers/PodcastController.php
Expand Up @@ -2,7 +2,10 @@
use Feeds;
use DB;
use Request;
use Image;
use Auth;
use App\Podcast;
use App\Item;
use Illuminate\Support\Facades\Redirect;

class PodcastController extends Controller {
Expand All @@ -23,15 +26,17 @@ public function __construct()
*/
public function index()
{
$feedUrls = DB::table('podcasts')->select('feed_url')->lists('feed_url');

$feed = Feeds::make($feedUrls);
$feed->set_cache_duration(3600);
$feed->set_item_limit(5);
$items = DB::table('items')
->where('user_id', '=', Auth::user()->id)
->orderBy('published_at','desc')->get();

$podcasts = DB::table('podcasts')
->where('user_id', '=', Auth::user()->id)
->get();

$data = array(
'title' => $feed->get_title(),
'permalink' => $feed->get_permalink(),
'items' => $feed->get_items(),
'podcasts' => $podcasts,
'items' => $items,
);

return view('podcasts.list', $data);
Expand Down Expand Up @@ -72,15 +77,40 @@ public function add()
// check if the feed's first item has an audio file in its enclosure
if(strpos($feed->get_items()[0]->get_enclosure()->get_type(),'audio') !== false)
{
$podcastMachineName = strtolower(preg_replace('/\s+/', '', $podcastName));

// Save the feed thumbnail to file system and save file path to database
$img = Image::make($feed->get_image_url())->resize(75, 75);
$img->save(public_path('images/' . $podcastMachineName . '.png'));

Podcast::create([
'name' => $podcastName ? $podcastName : '',
'machine_name' => strtolower(preg_replace('/\s+/', '', $podcastName)),
'feed_url' => Request::get('feed_url')
'name' => $podcastName ? $podcastName : '',
'machine_name' => $podcastMachineName,
'feed_url' => Request::get('feed_url'),
'feed_thumbnail_location' => 'images/' . $podcastMachineName . '.png',
'user_id' => Auth::user()->id
]);

foreach($feed->get_items() as $item)
{
Item::create([
'podcast_id' => DB::table('podcasts')
->select('id','machine_name')
->where('machine_name','=', $podcastMachineName)->first()->id,
'user_id' => Auth::user()->id,
'url' => $item->get_permalink(),
'audio_url' => $item->get_enclosure()->get_link(),
'title' => $item->get_title(),
'description' => strip_tags(str_limit($item->get_description(),100)),
'published_at' => $item->get_date('Y-m-d H:i:s')
]);
}

// @todo Podcast was added
return redirect('podcast/player');
}
else {
else
{
// @todo flash msg
return 'This doesn\'t seem to be an RSS feed with audio files. Please try another feed.';
}
Expand All @@ -91,7 +121,8 @@ public function add()
return 'Sorry, this feed cannot be imported. Please try another feed';
}
}
else {
else
{
// @todo use validation
return 'Invalid feed URL given.';
}
Expand All @@ -117,7 +148,7 @@ public function delete()
}
else
{
// @todo db delete failed
// @todo DB delete failed
}
}
else {
Expand Down
16 changes: 16 additions & 0 deletions app/Item.php
@@ -0,0 +1,16 @@
<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Item extends Model {

protected $fillable = ['user_id', 'podcast_id', 'title', 'description', 'url', 'audio_url','published_at'];

/**
* An item belongs to a podcast
*/
public function podcast()
{
return $this->belongsTo('App\Podcast');
}
}
10 changes: 9 additions & 1 deletion app/Podcast.php
Expand Up @@ -4,6 +4,14 @@

class Podcast extends Model {

protected $fillable = ['name', 'machine_name', 'feed_url', 'feed_thumbnail_location'];
protected $fillable = ['name', 'user_id', 'machine_name', 'feed_url', 'feed_thumbnail_location'];

/**
* A podcast has many items
*/
public function items()
{
return $this->hasMany('App\Item');
}

}
8 changes: 8 additions & 0 deletions app/User.php
Expand Up @@ -31,4 +31,12 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/
protected $hidden = ['password', 'remember_token'];

/**
* A user has many podcasts
*/
public function podcasts()
{
return $this->hasMany('App\Podcast');
}

}
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -8,7 +8,8 @@
"laravel/framework": "5.0.*",
"willvincent/feeds": "dev-master",
"barryvdh/laravel-debugbar": "^2.0",
"illuminate/html": "~5.0"
"illuminate/html": "~5.0",
"intervention/image": "^2.2"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
Expand Down
58 changes: 57 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion config/app.php
Expand Up @@ -148,6 +148,7 @@
'Barryvdh\Debugbar\ServiceProvider',
'Illuminate\View\ViewServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
'Intervention\Image\ImageServiceProvider',

],

Expand Down Expand Up @@ -199,7 +200,8 @@
'Feeds' => 'willvincent\Feeds\Facades\FeedsFacade',
'Debugbar' => 'Barryvdh\Debugbar\Facade',
'Form' => 'Illuminate\Html\FormFacade',
'Html' => 'Illuminate\Html\HtmlFacade'
'Html' => 'Illuminate\Html\HtmlFacade',
'Image' => 'Intervention\Image\Facades\Image',

],

Expand Down
20 changes: 20 additions & 0 deletions config/image.php
@@ -0,0 +1,20 @@
<?php

return array(

/*
|--------------------------------------------------------------------------
| Image Driver
|--------------------------------------------------------------------------
|
| Intervention Image supports "GD Library" and "Imagick" to process images
| internally. You may choose one of them according to your PHP
| configuration. By default PHP's "GD Library" implementation is used.
|
| Supported: "gd", "imagick"
|
*/

'driver' => 'gd'

);
12 changes: 9 additions & 3 deletions database/migrations/2015_06_07_015255_create_podcasts_table.php
Expand Up @@ -17,9 +17,15 @@ public function up()
$table->increments('id');
$table->timestamps();
$table->string('name');
$table->string('machine_name')->unique();
$table->string('feed_url')->unique();
$table->string('feed_thumbnail_location')->nullable()->unique();
$table->string('machine_name');
$table->string('feed_url');
$table->string('feed_thumbnail_location')->nullable();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->unique(['machine_name','user_id']);
});
}

Expand Down
47 changes: 47 additions & 0 deletions database/migrations/2015_06_07_220046_create_items_table.php
@@ -0,0 +1,47 @@
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateItemsTable extends Migration {

/**
* Setup database table for items in each podcast
*
* @return void
*/
public function up()
{
Schema::create('items', function(Blueprint $table)
{
$table->increments('id');
$table->timestamps();
$table->integer('user_id')->unsigned();
$table->string('title');
$table->longText('description');
$table->string('url');
$table->string('audio_url');
$table->date('published_at');
$table->integer('podcast_id')->unsigned();
$table->foreign('podcast_id')
->references('id')
->on('podcasts')
->onDelete('cascade');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('items');
}

}
2 changes: 1 addition & 1 deletion public/robots.txt
@@ -1,2 +1,2 @@
User-agent: *
Disallow:
Disallow: /
15 changes: 8 additions & 7 deletions resources/views/podcasts/list.blade.php
Expand Up @@ -24,21 +24,22 @@
@foreach ($items as $item)
<div class="row podcast-item-row">
<div class="col-md-3 podcast-thumbnail-container">
<img class="podcast-thumbnail" width="75" height="75" src="{{$item->get_feed()->get_image_url()}}" />
<p><small>{{ $item->get_date('jS M Y') }}</small></p>
<img class="podcast-thumbnail" width="75" height="75"
src="{{asset(App\Item::find($item->id)->podcast->feed_thumbnail_location)}}" />
<p><small>{{ date_format(date_create($item->published_at),'jS M Y') }}</small></p>
</div>
<div class="col-md-9">
<h4 class="podcast-title"><small>{{$item->get_feed()->get_title()}}</small></h4>
<h4 class="podcast-title"><small>{{App\Item::find($item->id)->podcast->name}}</small></h4>
<h3 class="podcast-item-title">
<a target="_blank" href="{{ $item->get_permalink() }}">{{ $item->get_title() }}</a>
<a target="_blank" href="{{ $item->url }}">{{ $item->title }}</a>
</h3>
<p class="podcast-item-description">{{strip_tags(str_limit($item->get_description(),100))}}
<p class="podcast-item-description">{{ $item->description}}
<br/>
<a class="read-more" target="_blank" href="{{ $item->get_permalink() }}"><small>Read More</small></a>
<a class="read-more" target="_blank" href="{{ $item->url }}"><small>Read More</small></a>
</p>
<div class="player-action-list">
<ul class="list-inline">
<li class='play' data-src='{{ $item->get_enclosure()->get_link() }}'>
<li class='play' data-src='{{ $item->audio_url}}'>
<button type="button" class="btn-sm btn-primary">Play</button>
</li>
<li class="pause">
Expand Down
8 changes: 4 additions & 4 deletions resources/views/podcasts/manage.blade.php
Expand Up @@ -9,8 +9,8 @@
<table class="table">
<thead>
<tr>
<th>Created on</th>
<th>Name</th>
<th>Added on</th>
<th>Podcast Name</th>
</tr>
</thead>
<tbody>
Expand All @@ -25,11 +25,11 @@
</table>
@endif

<h4>Add a feed</h4>
<h4>Add a podcast feed</h4>
{!! Form::model($podcast = new \App\Podcast, ['method' =>'POST','action' => ['PodcastController@add']]) !!}
<div class="form-group">
{!! Form::text('feed_url', null,
['class' => 'form-control','required','placeholder' => 'Enter Feed Url here: http://example.com/feed']) !!}
['class' => 'form-control','required','placeholder' => 'Enter a Podcast Feed Url here: http://example.com/feed']) !!}
</div>

<div class="form-group">
Expand Down

0 comments on commit c436a6d

Please sign in to comment.