示例#1
0
文件: Download.php 项目: phanan/koel
 /**
  * Generate the downloadable path for a song.
  *
  * @param Song $song
  *
  * @return string
  */
 protected function fromSong(Song $song)
 {
     if ($s3Params = $song->s3_params) {
         // The song is hosted on Amazon S3.
         // We download it back to our local server first.
         $localPath = rtrim(sys_get_temp_dir(), '/') . '/' . basename($s3Params['key']);
         $url = $song->getObjectStoragePublicUrl();
         abort_unless($url, 404);
         // The following function require allow_url_fopen to be ON.
         // We're just assuming that to be the case here.
         copy($url, $localPath);
     } else {
         // The song is hosted locally. Make sure the file exists.
         abort_unless(file_exists($song->path), 404);
         $localPath = $song->path;
     }
     // The BinaryFileResponse factory only accept ASCII-only file names.
     if (ctype_print($localPath)) {
         return $localPath;
     }
     // For those with high-byte characters in names, we copy it into a safe name
     // as a workaround.
     $newPath = rtrim(sys_get_temp_dir(), '/') . '/' . utf8_decode(basename($song->path));
     if ($s3Params) {
         // If the file is downloaded from S3, we rename it directly.
         // This will save us some disk space.
         rename($localPath, $newPath);
     } else {
         // Else we copy it to another file to not mess up the original one.
         copy($localPath, $newPath);
     }
     return $newPath;
 }
示例#2
0
 /**
  * Controller constructor.
  */
 public function __construct()
 {
     parent::__construct();
     $this->types = Enum::getTypes();
     abort_unless($this->types, 500, 'Enum Resources is empty!...');
     $this->switchType();
 }
示例#3
0
 /**
  * Remove a song whose info matches with data sent from AWS.
  *
  * @param RemoveSongRequest $request
  *
  * @return \Illuminate\Http\JsonResponse
  */
 public function remove(RemoveSongRequest $request)
 {
     abort_unless($song = Song::byPath("s3://{$request->bucket}/{$request->key}"), 404);
     $song->delete();
     event(new LibraryChanged());
     return response()->json();
 }
示例#4
0
 /**
  * Serve the callback request from Last.fm.
  *
  * @param Request $request
  * @param Lastfm  $lastfm
  *
  * @return \Illuminate\Http\Response
  */
 public function callback(Request $request, Lastfm $lastfm)
 {
     abort_unless($token = $request->input('token'), 500, 'Something wrong happened.');
     // Get the session key using the obtained token.
     abort_unless($sessionKey = $lastfm->getSessionKey($token), 500, 'Invalid token key.');
     $this->auth->user()->savePreference('lastfm_session_key', $sessionKey);
     return view('api.lastfm.callback');
 }
 /**
  * @param string $type
  *
  * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
  */
 public function enum($type)
 {
     abort_unless(in_array($type, ['language', 'security', 'writer', 'publisher', 'pplace']), 404);
     $this->buildHeading([trans("ilib::common.statistics"), trans("ilib::common.statistics_{$type}")], 'fa-bar-chart', ['#' => trans("ilib::common.statistics")]);
     $couters = DB::table('ebooks')->leftJoin('enums', "ebooks.{$type}_id", '=', 'enums.id')->groupBy('enums.title')->select(DB::raw('COUNT(*) AS enum_count'), 'enums.title as title')->orderBy('enum_count', 'desc')->get();
     $type_title = trans("ebook::common.{$type}_id");
     return view('ilib::backend.statistics.enum', compact('type_title', 'couters'));
 }
示例#6
0
 /**
  * BaseStreamer constructor.
  *
  * @param $song Song
  */
 public function __construct(Song $song)
 {
     $this->song = $song;
     abort_unless(file_exists($this->song->path), 404);
     // Hard code the content type instead of relying on PHP's fileinfo()
     // or even Symfony's MIMETypeGuesser, since they appear to be wrong sometimes.
     $this->contentType = 'audio/' . pathinfo($this->song->path, PATHINFO_EXTENSION);
     // Turn off error reporting to make sure our stream isn't interfered.
     @error_reporting(0);
 }
 /**
  * Redeem the given coupon code.
  *
  * @param  Request  $request
  * @param  Team  $team
  * @return Response
  */
 public function redeem(Request $request, Team $team)
 {
     abort_unless($request->user()->ownsTeam($team), 403);
     $this->validate($request, ['coupon' => 'required']);
     // We will verify that the coupon can actually be redeemed. In some cases even
     // valid coupons can not get redeemed by an existing user if this coupon is
     // running as a promotion for brand new registrations to the application.
     if (!$this->coupons->canBeRedeemed($request->coupon)) {
         return response()->json(['coupon' => ['This coupon code is invalid.']], 422);
     }
     Spark::interact(RedeemCoupon::class, [$team, $request->coupon]);
 }
示例#8
0
 /**
  * On-the-fly stream the current song while transcoding.
  */
 public function stream()
 {
     $ffmpeg = env('FFMPEG_PATH', '/usr/local/bin/ffmpeg');
     abort_unless(is_executable($ffmpeg), 500, 'Transcoding requires valid ffmpeg settings.');
     $bitRate = filter_var($this->bitrate, FILTER_SANITIZE_NUMBER_INT);
     // Since we can't really know the content length of a file while it's still being transcoded,
     // "calculating" it (like below) will be much likely to result in net::ERR_CONTENT_LENGTH_MISMATCH errors.
     // Better comment these for now.
     //
     // header('Accept-Ranges: bytes');
     // $bytes = round(($this->song->length * $bitRate * 1024) / 8);
     // header("Content-Length: $bytes");
     header('Content-Type: audio/mpeg');
     header('Content-Disposition: attachment; filename="' . basename($this->song->path) . '"');
     $args = ['-i ' . escapeshellarg($this->song->path), '-map 0:0', '-v 0', "-ab {$bitRate}k", '-f mp3', '-'];
     if ($this->startTime) {
         array_unshift($args, "-ss {$this->startTime}");
     }
     passthru("{$ffmpeg} " . implode($args, ' '));
 }
 /**
  * Update the given team's name.
  *
  * @param  Request  $request
  * @param  \Laravel\Spark\Team  $team
  * @return Response
  */
 public function update(Request $request, $team)
 {
     abort_unless($request->user()->ownsTeam($team), 404);
     $this->validate($request, ['name' => 'required|max:255']);
     $team->forceFill(['name' => $request->name])->save();
 }
示例#10
0
 /**
  * Download the invoice with the given ID.
  *
  * @param  Request  $request
  * @param  Team  $team
  * @param  string  $id
  * @return Response
  */
 public function download(Request $request, Team $team, $id)
 {
     abort_unless($request->user()->ownsTeam($team), 403);
     $invoice = $team->localInvoices()->where('id', $id)->firstOrFail();
     return $team->downloadInvoice($invoice->provider_id, ['id' => $invoice->id] + Spark::invoiceDataFor($team));
 }
示例#11
0
 /**
  * Stream the current song using the most basic PHP method: readfile()
  * Credits: DaveRandom @ http://stackoverflow.com/a/4451376/794641.
  */
 public function stream()
 {
     // Get the 'Range' header if one was sent
     if (isset($_SERVER['HTTP_RANGE'])) {
         // IIS/Some Apache versions
         $range = $_SERVER['HTTP_RANGE'];
     } elseif (function_exists('apache_request_headers') && ($apache = apache_request_headers())) {
         // Try Apache again
         $headers = [];
         foreach ($apache as $header => $val) {
             $headers[strtolower($header)] = $val;
         }
         $range = isset($headers['range']) ? $headers['range'] : false;
     } else {
         // We can't get the header/there isn't one set
         $range = false;
     }
     // Get the data range requested (if any)
     $fileSize = filesize($this->song->path);
     if ($range) {
         $partial = true;
         list($param, $range) = explode('=', $range);
         // Bad request - range unit is not 'bytes'
         abort_unless(strtolower(trim($param)) === 'bytes', 400);
         $range = explode(',', $range);
         $range = explode('-', $range[0]);
         // We only deal with the first requested range
         // Bad request - 'bytes' parameter is not valid
         abort_unless(count($range) === 2, 400);
         if ($range[0] === '') {
             // First number missing, return last $range[1] bytes
             $end = $fileSize - 1;
             $start = $end - intval($range[0]);
         } elseif ($range[1] === '') {
             // Second number missing, return from byte $range[0] to end
             $start = intval($range[0]);
             $end = $fileSize - 1;
         } else {
             // Both numbers present, return specific range
             $start = intval($range[0]);
             $end = intval($range[1]);
             if ($end >= $fileSize || !$start && (!$end || $end == $fileSize - 1)) {
                 // Invalid range/whole file specified, return whole file
                 $partial = false;
             }
         }
         $length = $end - $start + 1;
     } else {
         // No range requested
         $length = filesize($this->song->path);
         $partial = false;
     }
     // Send standard headers
     header("Content-Type: {$this->contentType}");
     header("Content-Length: {$length}");
     header('Content-Disposition: attachment; filename="' . basename($this->song->path) . '"');
     header('Accept-Ranges: bytes');
     // if requested, send extra headers and part of file...
     if ($partial) {
         header('HTTP/1.1 206 Partial Content');
         header("Content-Range: bytes {$start}-{$end}/{$fileSize}");
         // Error out if we can't read the file
         abort_unless($fp = fopen($this->song->path, 'r'), 500);
         if ($start) {
             fseek($fp, $start);
         }
         while ($length) {
             // Read in blocks of 8KB so we don't chew up memory on the server
             $read = $length > 8192 ? 8192 : $length;
             $length -= $read;
             echo fread($fp, $read);
         }
         fclose($fp);
     } else {
         // ...otherwise just send the whole file
         readfile($this->song->path);
     }
     exit;
 }
 /**
  * Update the team's extra billing information.
  *
  * @param  Request  $request
  * @param  Team  $team
  * @return Response
  */
 public function update(Request $request, Team $team)
 {
     abort_unless($request->user()->ownsTeam($team), 403);
     $this->validate($request, ['information' => 'max:2048']);
     $team->forceFill(['extra_billing_information' => $request->information])->save();
 }
 /**
  * Cancel / delete the given invitation.
  *
  * @param  Request  $request
  * @param  \Laravel\Spark\Invitation  $invitation
  * @return Response
  */
 public function destroy(Request $request, Invitation $invitation)
 {
     abort_unless($request->user()->ownsTeam($invitation->team), 404);
     $invitation->delete();
 }
示例#14
0
 /**
  * Cancel the team's subscription.
  *
  * @param  Request  $request
  * @param  Team  $team
  * @return Response
  */
 public function destroy(Request $request, Team $team)
 {
     abort_unless($request->user()->ownsTeam($team), 403);
     $team->subscription()->cancel();
     event(new SubscriptionCancelled($team->fresh()));
 }
示例#15
0
 /**
  * @param \Minhbang\Ebook\Ebook $ebook
  * @param string $slug
  *
  * @return bool
  */
 protected function checkPermission($ebook, $slug)
 {
     abort_unless($slug == $ebook->slug, 404);
     /** @var User $user */
     $user = user();
     /** @var Reader $reader */
     $reader = Reader::find($user->id);
     return $user->hasRole('tv.*') || $ebook->isPublished() && $reader && $reader->canRead($ebook);
 }
示例#16
0
 /**
  * Switch the current team the user is viewing.
  *
  * @param  Request  $request
  * @param  \Laravel\Spark\Team  $team
  * @return Response
  */
 public function switchCurrentTeam(Request $request, $team)
 {
     abort_unless($request->user()->onTeam($team), 404);
     $request->user()->switchToTeam($team);
     return back();
 }
 /**
  * Reject the given invitations.
  *
  * @param  Request  $request
  * @param  \Laravel\Spark\Invitation  $invitation
  * @return Response
  */
 public function reject(Request $request, Invitation $invitation)
 {
     abort_unless($request->user()->id == $invitation->user_id, 404);
     $invitation->delete();
 }
示例#18
0
 /**
  * Show the team settings dashboard.
  *
  * @param  Request  $request
  * @param  Team  $team
  * @return Response
  */
 public function show(Request $request, $team)
 {
     abort_unless($request->user()->onTeam($team), 404);
     return view('spark::settings.teams.team-settings', compact('team'));
 }
 /**
  * Update the given team member.
  *
  * @param  Request  $request
  * @param  \Laravel\Spark\Team  $team
  * @param  mixed  $member
  * @return Response
  */
 public function update(Request $request, $team, $member)
 {
     abort_unless($request->user()->ownsTeam($team), 404);
     $this->interaction($request, UpdateTeamMember::class, [$team, $member, $request->all()]);
 }
示例#20
0
 public static function findBySlug(string $slug) : Article
 {
     $article = Article::online()->where('slug->' . content_locale(), $slug)->first();
     abort_unless($article, 404);
     return $article;
 }
 /**
  * Update the payment method for the user.
  *
  * @param  UpdatePaymentMethodRequest  $request
  * @param  Team  $team
  * @return Response
  */
 public function update(UpdatePaymentMethodRequest $request, Team $team)
 {
     abort_unless($request->user()->ownsTeam($team), 403);
     Spark::interact(UpdatePaymentMethod::class, [$team, $request->all()]);
 }