Compare commits

..

3 Commits

  1. 21
      lib/DirScanner.php
  2. 4
      themes/beauty/controller/CommandController.php
  3. 12
      themes/beauty/controller/ListController.php
  4. 9
      themes/beauty/controller/SiteController.php
  5. 26
      themes/beauty/views/site/index.php
  6. 6
      www/css/beauty.css
  7. 4
      www/img/beauty/calendar.svg

21
lib/DirScanner.php

@ -69,6 +69,12 @@ Class DirScanner {
'jpeg', //图片 'jpeg', //图片
); );
public $exiftoolSupported = false;
public $exiftoolSupportFileExtensions = array(
'mp4', //视频
'mov', //视频
);
//暂未使用 //暂未使用
/* /*
protected $maxReadFilesize = array( //默认每种文件读取内容最大大小 protected $maxReadFilesize = array( //默认每种文件读取内容最大大小
@ -323,6 +329,21 @@ Class DirScanner {
if ($photo_create_time > 0) { if ($photo_create_time > 0) {
$data['original_ctime'] = $photo_create_time; $data['original_ctime'] = $photo_create_time;
} }
}else if ($this->exiftoolSupported && in_array($extension, $this->exiftoolSupportFileExtensions)) {
//try to exec command to get original create time of videos
try {
$output = shell_exec( sprintf("exiftool -createdate %s", escapeshellarg($realpath)) );
//output samples:
//Create Date : 2024:06:01 20:47:06
//Create Date : 0000:00:00 00:00:00
if (!empty($output) && strpos($output, ': 0000:') === false) {
$dateArr = explode(' : ', $output);
$data['original_ctime'] = strtotime($dateArr[1]);
}
}catch(Exception $e) {
//do nothing
}
} }
return $data; return $data;

4
themes/beauty/controller/CommandController.php

@ -144,6 +144,7 @@ eof;
//扫描媒体文件:图片、视频、音乐 //扫描媒体文件:图片、视频、音乐
//TODO: 把它们按年份、月份归类,并缓存到/runtime/cache/目录,方便前端展示读取 //TODO: 把它们按年份、月份归类,并缓存到/runtime/cache/目录,方便前端展示读取
//把当前扫描进度保存到单独的缓存文件,便于用户随时获取 //把当前扫描进度保存到单独的缓存文件,便于用户随时获取
//TODO: 没有original_ctime的视频文件调用exiftool获取拍摄时间
protected function scanMediaFiles($dirpath = '') { protected function scanMediaFiles($dirpath = '') {
$rootDir = __DIR__ . '/../../../www/' . FSC::$app['config']['content_directory']; $rootDir = __DIR__ . '/../../../www/' . FSC::$app['config']['content_directory'];
if (empty($dirpath)) { if (empty($dirpath)) {
@ -155,6 +156,9 @@ eof;
$scanner->setWebRoot(FSC::$app['config']['content_directory']); $scanner->setWebRoot(FSC::$app['config']['content_directory']);
$scanner->setRootDir($dirpath); $scanner->setRootDir($dirpath);
//尝试使用exiftool来获取视频的拍摄时间
$scanner->exiftoolSupported = true;
$maxScanDeep = 0; //最大扫描目录级数 $maxScanDeep = 0; //最大扫描目录级数
$dirTree = $scanner->scan($dirpath, $maxScanDeep); $dirTree = $scanner->scan($dirpath, $maxScanDeep);
$scanResults = $scanner->getScanResults(); $scanResults = $scanner->getScanResults();

12
themes/beauty/controller/ListController.php

@ -8,6 +8,8 @@ require_once __DIR__ . '/../../../plugins/Common.php';
require_once __DIR__ . '/../../../plugins/Html.php'; require_once __DIR__ . '/../../../plugins/Html.php';
Class ListController extends Controller { Class ListController extends Controller {
protected $dateIndexCacheKey = 'MainBotDateIndex';
protected $noOriginalCtimeFilesCacheKey = 'MainBotNoOriginalCtimeFiles';
public function actionIndex() { public function actionIndex() {
$cateId = $this->get('id', ''); $cateId = $this->get('id', '');
@ -140,7 +142,7 @@ Class ListController extends Controller {
} }
//图片、视频类型筛选支持 //图片、视频类型筛选支持
$allFiles = $scanResults[$cateId]['files']; $allFiles = !empty($scanResults[$cateId]['files']) ? $scanResults[$cateId]['files'] : [];
$showType = $this->get('show', 'all'); $showType = $this->get('show', 'all');
if ($showType == 'image' && !empty($scanResults[$cateId]['files'])) { if ($showType == 'image' && !empty($scanResults[$cateId]['files'])) {
$scanResults[$cateId]['files'] = array_filter($scanResults[$cateId]['files'], function($item) { $scanResults[$cateId]['files'] = array_filter($scanResults[$cateId]['files'], function($item) {
@ -300,10 +302,14 @@ Class ListController extends Controller {
$isAdminIp = Common::isAdminIp($this->getUserIp()); //判断是否拥有管理权限 $isAdminIp = Common::isAdminIp($this->getUserIp()); //判断是否拥有管理权限
//从缓存文件获取按年份、月份归类的索引数据
$cacheDataByDate = Common::getCacheFromFile($this->dateIndexCacheKey, 86400*365);
$viewName = '//site/index'; //共享视图 $viewName = '//site/index'; //共享视图
$params = compact( $params = compact(
'cateId', 'dirTree', 'scanResults', 'menus', 'htmlReadme', 'breadcrumbs', 'htmlCateReadme', 'cateId', 'dirTree', 'scanResults', 'menus', 'htmlReadme', 'breadcrumbs', 'htmlCateReadme',
'mp3File', 'page', 'pageSize', 'cacheDataId', 'copyright', 'showType', 'isAdminIp', 'allFiles' 'mp3File', 'page', 'pageSize', 'cacheDataId', 'copyright', 'showType', 'isAdminIp', 'allFiles',
'cacheDataByDate'
); );
return $this->render($viewName, $params, $pageTitle); return $this->render($viewName, $params, $pageTitle);
} }
@ -345,7 +351,7 @@ Class ListController extends Controller {
//缓存key统一生成,方便按规则获取上一级目录的缓存cid //缓存key统一生成,方便按规则获取上一级目录的缓存cid
protected function getBreadcrumbs($currentDir, $scanResults, $scanner) { protected function getBreadcrumbs($currentDir, $scanResults, $scanner) {
$webroot = FSC::$app['config']['content_directory']; $webroot = FSC::$app['config']['content_directory'];
$arr = explode($webroot, $currentDir['realpath']); $arr = !empty($currentDir['realpath']) ? explode($webroot, $currentDir['realpath']) : [];
$breads = array(); $breads = array();
if (count($arr) < 2) { if (count($arr) < 2) {

9
themes/beauty/controller/SiteController.php

@ -8,6 +8,8 @@ require_once __DIR__ . '/../../../plugins/Common.php';
require_once __DIR__ . '/../../../plugins/Html.php'; require_once __DIR__ . '/../../../plugins/Html.php';
Class SiteController extends Controller { Class SiteController extends Controller {
protected $dateIndexCacheKey = 'MainBotDateIndex';
protected $noOriginalCtimeFilesCacheKey = 'MainBotNoOriginalCtimeFiles';
public function actionIndex() { public function actionIndex() {
//获取数据 //获取数据
@ -257,11 +259,16 @@ Class SiteController extends Controller {
$isAdminIp = Common::isAdminIp($this->getUserIp()); //判断是否拥有管理权限 $isAdminIp = Common::isAdminIp($this->getUserIp()); //判断是否拥有管理权限
//从缓存文件获取按年份、月份归类的索引数据
$cacheDataByDate = Common::getCacheFromFile($this->dateIndexCacheKey, 86400*365);
$viewName = 'index'; $viewName = 'index';
$params = compact( $params = compact(
'page', 'pageSize', 'cacheDataId', 'showType', 'page', 'pageSize', 'cacheDataId', 'showType',
'dirTree', 'scanResults', 'menus', 'htmlReadme', 'htmlCateReadme', 'mp3File', 'copyright', 'dirTree', 'scanResults', 'menus', 'htmlReadme', 'htmlCateReadme', 'mp3File', 'copyright',
'alertWarning', 'isAdminIp', 'allFiles' 'alertWarning', 'isAdminIp', 'allFiles',
'cacheDataByDate'
); );
return $this->render($viewName, $params, $pageTitle); return $this->render($viewName, $params, $pageTitle);
} }

26
themes/beauty/views/site/index.php

@ -34,7 +34,6 @@ $main_view_cls = $menu_ext_status == 'opened' ? '' : 'full';
</div> </div>
<a class="navbar-brand" href="/"> <a class="navbar-brand" href="/">
<!--img class="verMiddle" src="/content/machete_icon.png" alt="logo图片"-->
<span class="verMiddle"><?php echo $pageTitle; ?></span> <span class="verMiddle"><?php echo $pageTitle; ?></span>
</a> </a>
</div> </div>
@ -57,14 +56,37 @@ $main_view_cls = $menu_ext_status == 'opened' ? '' : 'full';
</form> </form>
*/ ?> */ ?>
<!--侧边栏-->
<ul class="nav navbar-fixed-left <?=$menu_expand_icon_cls?>"> <ul class="nav navbar-fixed-left <?=$menu_expand_icon_cls?>">
<li class="menu-title">按年月归类</li>
<?php
if (!empty($viewData['cacheDataByDate'])) {
foreach($viewData['cacheDataByDate'] as $year => $ids) {
$intYear = str_replace('y', '', $year);
echo <<<eof
<li><a href="###"><img src="/img/beauty/calendar.svg" alt="calendar" width="17" class="menu-icon"> {$intYear}年</a></li>
eof;
}
}else {
echo <<<eof
<li class="text-center">
还没有索引数据!
<button class="btnStartScan btn btn-xs btn-primary disabled">点我开始扫描</button>
</li>
eof;
}
?>
<li class="menu-title mt-1">目录</li>
<?php <?php
$breadcrumbs = !empty($viewData['breadcrumbs']) ? $viewData['breadcrumbs'] : []; $breadcrumbs = !empty($viewData['breadcrumbs']) ? $viewData['breadcrumbs'] : [];
if (!empty($viewData['menus'])) { //只显示第一级目录 if (!empty($viewData['menus'])) { //只显示第一级目录
foreach ($viewData['menus'] as $index => $item) { foreach ($viewData['menus'] as $index => $item) {
$selected = $item['id'] == $selectedId || (!empty($breadcrumbs) && $item['id'] == $breadcrumbs[0]['id']) ? 'active' : ''; $selected = $item['id'] == $selectedId || (!empty($breadcrumbs) && $item['id'] == $breadcrumbs[0]['id']) ? 'active' : '';
echo <<<eof echo <<<eof
<li class="{$selected}"><a href="{$item['path']}">{$item['directory']}</a></li> <li class="{$selected}"><a href="{$item['path']}">
<img src="/img/beauty/folder.svg" alt="directories" width="17" class="menu-icon">
{$item['directory']}
</a></li>
eof; eof;
} }
} }

6
www/css/beauty.css

@ -65,6 +65,7 @@ a:link{text-decoration:none}
padding-bottom:3em; padding-bottom:3em;
padding-top:10px; padding-top:10px;
} }
.navbar-fixed-left li a{padding-left:5px;padding-right:5px}
.navbar-fixed-left .active a{background-color:#e7e7e7;color:#555} .navbar-fixed-left .active a{background-color:#e7e7e7;color:#555}
.lampshow .navbar-fixed-left{background-color:#222} .lampshow .navbar-fixed-left{background-color:#222}
.lampshow .navbar-fixed-left a{color:#DDD} .lampshow .navbar-fixed-left a{color:#DDD}
@ -87,8 +88,9 @@ a:link{text-decoration:none}
.im_item .btn-set-snap{display:none;position:absolute;top:5px;right:5px;opacity:0.8} .im_item .btn-set-snap{display:none;position:absolute;top:5px;right:5px;opacity:0.8}
.im_item:hover .btn-set-snap{display:inline-block} .im_item:hover .btn-set-snap{display:inline-block}
.navbar-fixed-left .menu-title{font-size:12px;color:#999;padding-left:5px}
.navbar-fixed-left .expand-icon{position:fixed;top:58px;left:130px;cursor:pointer;padding:5px} .navbar-fixed-left .menu-icon{vertical-align:text-top}
.navbar-fixed-left .expand-icon{position:fixed;top:54px;left:130px;cursor:pointer;padding:5px}
.navbar-fixed-left.closed{width:28px;overflow:hidden} .navbar-fixed-left.closed{width:28px;overflow:hidden}
.navbar-fixed-left.closed li{display:none} .navbar-fixed-left.closed li{display:none}
.navbar-fixed-left.closed li.expand-icon{display:block;left:5px} .navbar-fixed-left.closed li.expand-icon{display:block;left:5px}

4
www/img/beauty/calendar.svg

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16">
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
</svg>

After

Width:  |  Height:  |  Size: 362 B

Loading…
Cancel
Save