Added command to update all courses and chapters, downloading videos and checking video size is split into two queues, chapters can be mark to sync individually, updated readme, check if subscription is active, playback rate controll,
This commit is contained in:
76
README.md
76
README.md
@@ -1,64 +1,32 @@
|
|||||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400"></a></p>
|
|
||||||
|
|
||||||
<p align="center">
|
## Commands
|
||||||
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## About Laravel
|
Updates information about courses and chapters
|
||||||
|
|
||||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
```php
|
||||||
|
php artisan symfonycast:update
|
||||||
|
```
|
||||||
|
|
||||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
Dispatch chapters marked as sync offline to queue for download
|
||||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
|
||||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
|
||||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
|
||||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
|
||||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
|
||||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
|
||||||
|
|
||||||
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
```php
|
||||||
|
php artisan symfonycast:sync
|
||||||
|
```
|
||||||
|
Dispatch chapters without file size to queue for update
|
||||||
|
|
||||||
## Learning Laravel
|
```php
|
||||||
|
php artisan symfonycast:video_size
|
||||||
|
```
|
||||||
|
|
||||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
|
## Queues
|
||||||
|
|
||||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
Downloading chapters marked as sync offline:
|
||||||
|
|
||||||
## Laravel Sponsors
|
```php
|
||||||
|
php artisan queue:work --queue=downloadVideoFile
|
||||||
|
```
|
||||||
|
Get information about file size of chapters:
|
||||||
|
|
||||||
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
|
```php
|
||||||
|
php artisan queue:work --queue=getVideoFileSize
|
||||||
### Premium Partners
|
```
|
||||||
|
|
||||||
- **[Vehikl](https://vehikl.com/)**
|
|
||||||
- **[Tighten Co.](https://tighten.co)**
|
|
||||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
|
||||||
- **[64 Robots](https://64robots.com)**
|
|
||||||
- **[Cubet Techno Labs](https://cubettech.com)**
|
|
||||||
- **[Cyber-Duck](https://cyber-duck.co.uk)**
|
|
||||||
- **[Many](https://www.many.co.uk)**
|
|
||||||
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
|
|
||||||
- **[DevSquad](https://devsquad.com)**
|
|
||||||
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
|
|
||||||
- **[OP.GG](https://op.gg)**
|
|
||||||
- **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)**
|
|
||||||
- **[Lendio](https://lendio.com)**
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
|
||||||
|
|
||||||
## Code of Conduct
|
|
||||||
|
|
||||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
|
||||||
|
|
||||||
## Security Vulnerabilities
|
|
||||||
|
|
||||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
|
||||||
|
|||||||
34
app/Console/Commands/Update.php
Normal file
34
app/Console/Commands/Update.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Http\SymfonyCastDl\SymfonyCastDlService;
|
||||||
|
use App\Jobs\DownloadVideoFile;
|
||||||
|
use App\Jobs\GetVideoFileSize;
|
||||||
|
use App\Models\Chapter;
|
||||||
|
use App\Models\Course;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class Update extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'symfonycast:update';
|
||||||
|
|
||||||
|
protected $description = 'Updates information about courses and chapters';
|
||||||
|
|
||||||
|
public function handle(SymfonyCastDlService $symfonyCastDlService)
|
||||||
|
{
|
||||||
|
if (!$symfonyCastDlService->isSubscriptionActive()) {
|
||||||
|
$this->error('To fully update courses and chapters you need active subscription');
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
$this->info('Start updating courses');
|
||||||
|
$courses = $symfonyCastDlService->updateCourses();
|
||||||
|
$this->output->success(count($courses) . ' courses updated');
|
||||||
|
$this->output->info('Start updating each course chapters');
|
||||||
|
$this->withProgressBar($courses, function (Course $course) use ($symfonyCastDlService) {
|
||||||
|
$symfonyCastDlService->updateChapters($course);
|
||||||
|
});
|
||||||
|
$this->output->success('Course chapters updated.');
|
||||||
|
return self::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Controllers/Chapter/Sync.php
Normal file
19
app/Http/Controllers/Chapter/Sync.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Chapter;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Jobs\DownloadVideoFile;
|
||||||
|
use App\Models\Chapter;
|
||||||
|
use App\Models\Course;
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
|
||||||
|
class Sync extends Controller
|
||||||
|
{
|
||||||
|
public function __invoke(Course $course, Chapter $chapter): RedirectResponse
|
||||||
|
{
|
||||||
|
$chapter->update(['sync_offline' => 1]);
|
||||||
|
DownloadVideoFile::dispatch($chapter->id);
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,13 +19,8 @@ class Index extends Controller
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
$request->whenHas('order', fn($order) => $courses->orderby($order, $request->dir));
|
$request->whenHas('order', fn($order) => $courses->orderby($order, $request->dir));
|
||||||
$request->whenMissing('order', fn() => $courses->orderby('name'));
|
$request->whenMissing('order', fn() => $courses->orderby('published_at', 'desc'));
|
||||||
$courses = $courses->get();
|
$courses = $courses->get();
|
||||||
return view('index', compact(['courses']));
|
return view('index', compact(['courses']));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function download(SymfonyCastDlService $symfonyCastDlService)
|
|
||||||
{
|
|
||||||
$symfonyCastDlService->getInfo();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,8 +67,12 @@ class HtmlParser
|
|||||||
|
|
||||||
public function getVideoSource(Response $respose): ?string
|
public function getVideoSource(Response $respose): ?string
|
||||||
{
|
{
|
||||||
$document = new Document($respose->getBody()->getContents());
|
return (new Document($respose->getBody()->getContents()))->first('video source')?->getAttribute('src');
|
||||||
return $document->first('video source')?->getAttribute('src');
|
}
|
||||||
|
|
||||||
|
public function isSubscriptionActive(Response $respose): bool
|
||||||
|
{
|
||||||
|
return (new Document($respose->getBody()->getContents()))->has('.subscription-status .i-active');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ namespace App\Http\SymfonyCastDl;
|
|||||||
use App\Jobs\GetVideoFileSize;
|
use App\Jobs\GetVideoFileSize;
|
||||||
use App\Models\Chapter;
|
use App\Models\Chapter;
|
||||||
use App\Models\Course;
|
use App\Models\Course;
|
||||||
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
use GuzzleHttp\TransferStats;
|
use GuzzleHttp\TransferStats;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use JetBrains\PhpStorm\NoReturn;
|
use JetBrains\PhpStorm\NoReturn;
|
||||||
|
|
||||||
class SymfonyCastDlService
|
class SymfonyCastDlService
|
||||||
@@ -33,26 +35,34 @@ class SymfonyCastDlService
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInfo(): void
|
/**
|
||||||
|
* @return Collection
|
||||||
|
* @throws GuzzleException
|
||||||
|
*/
|
||||||
|
public function updateCourses(): Collection
|
||||||
{
|
{
|
||||||
$coursePage = $this->client->get('courses/filtering');
|
$coursePage = $this->client->get('courses/filtering');
|
||||||
$courses = $this->htmlParser->getCourses($coursePage);
|
$courses = $this->htmlParser->getCourses($coursePage);
|
||||||
$courses->each->save();
|
return $courses->each->save();
|
||||||
/** @var Course $course */
|
|
||||||
foreach ($courses as $course) {
|
|
||||||
$singleCoursePage = $this->client->get('/screencast/' . $course->link);
|
|
||||||
$chapters = $this->htmlParser->getCourseDetails($singleCoursePage, $course->id);
|
|
||||||
$chapters->each->save();
|
|
||||||
$chapters->each(fn($chapter) => GetVideoFileSize::dispatch($chapter->id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateCourse(Course $course): void
|
/**
|
||||||
|
* @param Course $course
|
||||||
|
* @return Collection
|
||||||
|
* @throws GuzzleException
|
||||||
|
*/
|
||||||
|
public function updateChapters(Course $course): Collection
|
||||||
{
|
{
|
||||||
$singleCoursePage = $this->client->get('/screencast/' . $course->link);
|
$singleCoursePage = $this->client->get('/screencast/' . $course->link);
|
||||||
$chapters = $this->htmlParser->getCourseDetails($singleCoursePage, $course->id);
|
$chapters = $this->htmlParser->getCourseDetails($singleCoursePage, $course->id);
|
||||||
$chapters->each->save();
|
$chapters->each->save();
|
||||||
$chapters->each(fn($chapter) => GetVideoFileSize::dispatch($chapter->id));
|
$chapters->each(fn($chapter) => GetVideoFileSize::dispatch($chapter->id));
|
||||||
|
return $chapters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSubscriptionActive(): bool
|
||||||
|
{
|
||||||
|
return $this->htmlParser->isSubscriptionActive($this->client->get('/profile/show'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChapterInfo(Chapter $chapter): ?string
|
public function getChapterInfo(Chapter $chapter): ?string
|
||||||
@@ -89,5 +99,7 @@ class SymfonyCastDlService
|
|||||||
['sink' => $chapter->video_path],
|
['sink' => $chapter->video_path],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$chapter->video_size = filesize($chapter->video_path);
|
||||||
|
$chapter->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,20 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
class DownloadVideoFile implements ShouldQueue
|
class DownloadVideoFile implements ShouldQueue, ShouldBeUnique
|
||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
public const NAME = 'downloadVideoFile';
|
||||||
|
|
||||||
public function __construct(private int $chapterId)
|
public function __construct(private int $chapterId)
|
||||||
{
|
{
|
||||||
|
$this->onQueue(self::NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function uniqueId(): string
|
||||||
|
{
|
||||||
|
return $this->chapterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(SymfonyCastDlService $symfonyCastDlService)
|
public function handle(SymfonyCastDlService $symfonyCastDlService)
|
||||||
|
|||||||
@@ -11,12 +11,20 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
class GetVideoFileSize implements ShouldQueue
|
class GetVideoFileSize implements ShouldQueue, ShouldBeUnique
|
||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
public const NAME = 'getVideoFileSize';
|
||||||
|
|
||||||
public function __construct(private int $chapterId)
|
public function __construct(private int $chapterId)
|
||||||
{
|
{
|
||||||
|
$this->onQueue(self::NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function uniqueId(): string
|
||||||
|
{
|
||||||
|
return $this->chapterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(SymfonyCastDlService $symfonyCastDlService)
|
public function handle(SymfonyCastDlService $symfonyCastDlService)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"laravel/sail": "^1.0.1",
|
"laravel/sail": "^1.0.1",
|
||||||
"mockery/mockery": "^1.4.4",
|
"mockery/mockery": "^1.4.4",
|
||||||
"nunomaduro/collision": "^6.1",
|
"nunomaduro/collision": "^6.1",
|
||||||
|
"phpspec/phpspec": "^7.4",
|
||||||
"phpunit/phpunit": "^9.5.10",
|
"phpunit/phpunit": "^9.5.10",
|
||||||
"spatie/laravel-ignition": "^1.0"
|
"spatie/laravel-ignition": "^1.0"
|
||||||
},
|
},
|
||||||
|
|||||||
413
composer.lock
generated
413
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "394ff81206d4ce7c5805b59c06e517fd",
|
"content-hash": "682e19ac9391daeae8301a6cee88c5df",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
@@ -6719,6 +6719,417 @@
|
|||||||
},
|
},
|
||||||
"time": "2022-02-21T01:04:05+00:00"
|
"time": "2022-02-21T01:04:05+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "phpdocumentor/reflection-common",
|
||||||
|
"version": "2.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
|
||||||
|
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
|
||||||
|
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2 || ^8.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-2.x": "2.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"phpDocumentor\\Reflection\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jaap van Otterdijk",
|
||||||
|
"email": "opensource@ijaap.nl"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
|
||||||
|
"homepage": "http://www.phpdoc.org",
|
||||||
|
"keywords": [
|
||||||
|
"FQSEN",
|
||||||
|
"phpDocumentor",
|
||||||
|
"phpdoc",
|
||||||
|
"reflection",
|
||||||
|
"static analysis"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
|
||||||
|
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
|
||||||
|
},
|
||||||
|
"time": "2020-06-27T09:03:43+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpdocumentor/reflection-docblock",
|
||||||
|
"version": "5.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||||
|
"reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
|
||||||
|
"reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-filter": "*",
|
||||||
|
"php": "^7.2 || ^8.0",
|
||||||
|
"phpdocumentor/reflection-common": "^2.2",
|
||||||
|
"phpdocumentor/type-resolver": "^1.3",
|
||||||
|
"webmozart/assert": "^1.9.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"mockery/mockery": "~1.3.2",
|
||||||
|
"psalm/phar": "^4.8"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "5.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"phpDocumentor\\Reflection\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mike van Riel",
|
||||||
|
"email": "me@mikevanriel.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jaap van Otterdijk",
|
||||||
|
"email": "account@ijaap.nl"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
|
||||||
|
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
|
||||||
|
},
|
||||||
|
"time": "2021-10-19T17:43:47+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpdocumentor/type-resolver",
|
||||||
|
"version": "1.7.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||||
|
"reference": "dfc078e8af9c99210337325ff5aa152872c98714"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/dfc078e8af9c99210337325ff5aa152872c98714",
|
||||||
|
"reference": "dfc078e8af9c99210337325ff5aa152872c98714",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/deprecations": "^1.0",
|
||||||
|
"php": "^7.4 || ^8.0",
|
||||||
|
"phpdocumentor/reflection-common": "^2.0",
|
||||||
|
"phpstan/phpdoc-parser": "^1.13"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-tokenizer": "*",
|
||||||
|
"phpbench/phpbench": "^1.2",
|
||||||
|
"phpstan/extension-installer": "^1.1",
|
||||||
|
"phpstan/phpstan": "^1.8",
|
||||||
|
"phpstan/phpstan-phpunit": "^1.1",
|
||||||
|
"phpunit/phpunit": "^9.5",
|
||||||
|
"rector/rector": "^0.13.9",
|
||||||
|
"vimeo/psalm": "^4.25"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-1.x": "1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"phpDocumentor\\Reflection\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mike van Riel",
|
||||||
|
"email": "me@mikevanriel.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
|
||||||
|
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.1"
|
||||||
|
},
|
||||||
|
"time": "2023-03-27T19:02:04+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpspec/php-diff",
|
||||||
|
"version": "v1.1.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpspec/php-diff.git",
|
||||||
|
"reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpspec/php-diff/zipball/fc1156187f9f6c8395886fe85ed88a0a245d72e9",
|
||||||
|
"reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Diff": "lib/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Chris Boulton",
|
||||||
|
"homepage": "http://github.com/chrisboulton"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/phpspec/php-diff/tree/v1.1.3"
|
||||||
|
},
|
||||||
|
"time": "2020-09-18T13:47:07+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpspec/phpspec",
|
||||||
|
"version": "7.4.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpspec/phpspec.git",
|
||||||
|
"reference": "28faa87d1151a15848166226f33de61cb7107d0d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/28faa87d1151a15848166226f33de61cb7107d0d",
|
||||||
|
"reference": "28faa87d1151a15848166226f33de61cb7107d0d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/instantiator": "^1.0.5 || ^2",
|
||||||
|
"ext-tokenizer": "*",
|
||||||
|
"php": "^7.3 || 8.0.* || 8.1.* || 8.2.*",
|
||||||
|
"phpspec/php-diff": "^1.0.0",
|
||||||
|
"phpspec/prophecy": "^1.9",
|
||||||
|
"sebastian/exporter": "^3.0 || ^4.0 || ^5.0",
|
||||||
|
"symfony/console": "^3.4 || ^4.4 || ^5.0 || ^6.0",
|
||||||
|
"symfony/event-dispatcher": "^3.4 || ^4.4 || ^5.0 || ^6.0",
|
||||||
|
"symfony/finder": "^3.4 || ^4.4 || ^5.0 || ^6.0",
|
||||||
|
"symfony/process": "^3.4 || ^4.4 || ^5.0 || ^6.0",
|
||||||
|
"symfony/yaml": "^3.4 || ^4.4 || ^5.0 || ^6.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"sebastian/comparator": "<1.2.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"behat/behat": "^3.3",
|
||||||
|
"phpunit/phpunit": "^8.0 || ^9.0 || ^10.0",
|
||||||
|
"symfony/filesystem": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
||||||
|
"vimeo/psalm": "^4.3 || ^5.2"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"phpspec/nyan-formatters": "Adds Nyan formatters"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/phpspec"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "7.4.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"PhpSpec": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Konstantin Kudryashov",
|
||||||
|
"email": "ever.zet@gmail.com",
|
||||||
|
"homepage": "http://everzet.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Marcello Duarte",
|
||||||
|
"homepage": "http://marcelloduarte.net/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ciaran McNulty",
|
||||||
|
"homepage": "https://ciaranmcnulty.com/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Specification-oriented BDD framework for PHP 7.1+",
|
||||||
|
"homepage": "http://phpspec.net/",
|
||||||
|
"keywords": [
|
||||||
|
"BDD",
|
||||||
|
"SpecBDD",
|
||||||
|
"TDD",
|
||||||
|
"spec",
|
||||||
|
"specification",
|
||||||
|
"testing",
|
||||||
|
"tests"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/phpspec/phpspec/issues",
|
||||||
|
"source": "https://github.com/phpspec/phpspec/tree/7.4.0"
|
||||||
|
},
|
||||||
|
"time": "2023-04-21T13:17:48+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpspec/prophecy",
|
||||||
|
"version": "v1.17.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpspec/prophecy.git",
|
||||||
|
"reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/15873c65b207b07765dbc3c95d20fdf4a320cbe2",
|
||||||
|
"reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/instantiator": "^1.2 || ^2.0",
|
||||||
|
"php": "^7.2 || 8.0.* || 8.1.* || 8.2.*",
|
||||||
|
"phpdocumentor/reflection-docblock": "^5.2",
|
||||||
|
"sebastian/comparator": "^3.0 || ^4.0",
|
||||||
|
"sebastian/recursion-context": "^3.0 || ^4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpspec/phpspec": "^6.0 || ^7.0",
|
||||||
|
"phpstan/phpstan": "^1.9",
|
||||||
|
"phpunit/phpunit": "^8.0 || ^9.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Prophecy\\": "src/Prophecy"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Konstantin Kudryashov",
|
||||||
|
"email": "ever.zet@gmail.com",
|
||||||
|
"homepage": "http://everzet.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Marcello Duarte",
|
||||||
|
"email": "marcello.duarte@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Highly opinionated mocking framework for PHP 5.3+",
|
||||||
|
"homepage": "https://github.com/phpspec/prophecy",
|
||||||
|
"keywords": [
|
||||||
|
"Double",
|
||||||
|
"Dummy",
|
||||||
|
"fake",
|
||||||
|
"mock",
|
||||||
|
"spy",
|
||||||
|
"stub"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/phpspec/prophecy/issues",
|
||||||
|
"source": "https://github.com/phpspec/prophecy/tree/v1.17.0"
|
||||||
|
},
|
||||||
|
"time": "2023-02-02T15:41:36+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpstan/phpdoc-parser",
|
||||||
|
"version": "1.20.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||||
|
"reference": "90490bd8fd8530a272043c4950c180b6d0cf5f81"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/90490bd8fd8530a272043c4950c180b6d0cf5f81",
|
||||||
|
"reference": "90490bd8fd8530a272043c4950c180b6d0cf5f81",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||||
|
"phpstan/extension-installer": "^1.0",
|
||||||
|
"phpstan/phpstan": "^1.5",
|
||||||
|
"phpstan/phpstan-phpunit": "^1.1",
|
||||||
|
"phpstan/phpstan-strict-rules": "^1.0",
|
||||||
|
"phpunit/phpunit": "^9.5",
|
||||||
|
"symfony/process": "^5.2"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PHPStan\\PhpDocParser\\": [
|
||||||
|
"src/"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||||
|
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.2"
|
||||||
|
},
|
||||||
|
"time": "2023-04-22T12:59:35+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
"version": "9.2.26",
|
"version": "9.2.26",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
<th>Sync offline</th>
|
<th>Sync offline</th>
|
||||||
<th>Synced offline</th>
|
<th>Synced offline</th>
|
||||||
<th>File size</th>
|
<th>File size</th>
|
||||||
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@foreach($course->chapters()->get() as $chapter)
|
@foreach($course->chapters()->get() as $chapter)
|
||||||
@@ -24,6 +25,12 @@
|
|||||||
<td>{{ $chapter->sync_offline?'Yes':'no' }}</td>
|
<td>{{ $chapter->sync_offline?'Yes':'no' }}</td>
|
||||||
<td>{{ $chapter->is_video_file?'Yes':'-' }}</td>
|
<td>{{ $chapter->is_video_file?'Yes':'-' }}</td>
|
||||||
<td>{{ $chapter->video_size_human }}</td>
|
<td>{{ $chapter->video_size_human }}</td>
|
||||||
|
<td class="text-end">
|
||||||
|
@if(!$chapter->sync_offline)
|
||||||
|
<a
|
||||||
|
href="{{ route('course.chapter.sync', ['course' => $chapter->course->id,'chapter' => $chapter->id]) }}">sync</a>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th>
|
<th>
|
||||||
<a href="?order=name&dir={{ request()->has('dir')? ['asc'=>'desc', 'desc'=>'asc'][request()->dir]: 'desc'}}">Name</a>
|
|
||||||
|
<a href="{{ route('index', ['order' => 'name', 'dir' => request()->whenHas('dir', fn($dir) => ['asc'=>'desc', 'desc'=>'asc'][$dir], fn() => 'desc')]) }}">Name</a>
|
||||||
</th>
|
</th>
|
||||||
<th>Tracks</th>
|
<th>Tracks</th>
|
||||||
<th>Sync</th>
|
<th>Sync</th>
|
||||||
@@ -21,7 +22,7 @@
|
|||||||
<td class="align-middle">
|
<td class="align-middle">
|
||||||
<a class="text-decoration-none"
|
<a class="text-decoration-none"
|
||||||
href="{{ route('course.index', ['course' => $course->id]) }}">{{ $course->name }}</a>
|
href="{{ route('course.index', ['course' => $course->id]) }}">{{ $course->name }}</a>
|
||||||
<p class="text-muted">
|
<p class="">
|
||||||
course status: <span class="fw-lighter">{{ $course->status }}</span>
|
course status: <span class="fw-lighter">{{ $course->status }}</span>
|
||||||
published: <span class="fw-lighter"><a
|
published: <span class="fw-lighter"><a
|
||||||
href="?order=published_at&dir={{ request()->has('dir')? ['asc'=>'desc', 'desc'=>'asc'][request()->dir]: 'desc'}}"><abbr
|
href="?order=published_at&dir={{ request()->has('dir')? ['asc'=>'desc', 'desc'=>'asc'][request()->dir]: 'desc'}}"><abbr
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use App\Http\Controllers\ChapterController;
|
use App\Http\Controllers\ChapterController;
|
||||||
use App\Http\Controllers\Course;
|
use App\Http\Controllers\Course;
|
||||||
|
use App\Http\Controllers\Chapter;
|
||||||
use App\Http\Controllers\CourseController;
|
use App\Http\Controllers\CourseController;
|
||||||
use App\Http\Controllers\Index;
|
use App\Http\Controllers\Index;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
@@ -14,6 +15,7 @@ Route::prefix('course')->group(function () {
|
|||||||
Route::get('/{course}/sync', Course\Sync::class)->name('course.sync');
|
Route::get('/{course}/sync', Course\Sync::class)->name('course.sync');
|
||||||
Route::get('/{course}/update', Course\Update::class)->name('course.update');
|
Route::get('/{course}/update', Course\Update::class)->name('course.update');
|
||||||
Route::get('/{course}/chapter/{chapter}', ChapterController::class)->name('course.chapter');
|
Route::get('/{course}/chapter/{chapter}', ChapterController::class)->name('course.chapter');
|
||||||
|
Route::get('/{course}/chapter/{chapter}/sync', Chapter\Sync::class)->name('course.chapter.sync');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user