Вы не зашли.
#1.
tipsun
Off
(19)
Moderator
2011.04.26 16:04
Дописал, наконец, свой микроГовноЗагрузЦентр. Ура!
- - - -
Отрываю от сердца...
Пример:
tipsun.h2m.ru
Отредактировано tipsun (2011.05.02 17:05)
#2.
tipsun
Off
(19)
Moderator
2011.04.26 20:08
Добавил транслит папкэ
- - - -
Какие рекомендации, кроме логика/разметка раздельно?
начнем с того, что зачем это все в 1 файле?
#4.
tipsun
Off
(19)
Moderator
2011.04.26 21:09
Т.к. он единственный, пока что.
Сейчас исправлю.
Отредактировано tipsun (2011.04.27 21:09)
#5.
tipsun
Off
(19)
Moderator
2011.04.27 22:10
Просто не терпится все исправить и начать заливать картинки
Отредактировано tipsun (2011.04.28 21:09)
#6.
OloLo
Off
(1)
Участник
2011.04.27 23:11
Интересный зц ))Хотел посмотреть как мп3 файлы выводит,но в папках ещё не одного файла нету(((
Добавлено спустя 4 минуты 25 секунд: в граббе мп3 поиска,на хомяке ошибку выдает в 8 строке(
#7.
tipsun
Off
(19)
Moderator
2011.04.27 23:11
Потом поправлю, на сегодня достаточно говнокода...
- - - -
Как обычный файл мр3, даже иконка не будет меняться... Никакой дополн. инфы.
- - - -
Со временем исправлю ошибки, надеюсь... Если конечно подскажут тут. По функциональности может ещё добавлю туда сортировку сначала папки, потом файлы и ещё сортировку по времени размещения или имени файла. Этим всё и ограничится.
Отредактировано tipsun (2011.04.27 23:11)
#8.
OloLo
Off
(1)
Участник
2011.04.27 23:11
Закинь в директорию какую нибудь мп3 мелкую))))
Добавлено спустя 1 минуту 13 секунд: tipsun написал:
Потом поправлю, на сегодня достаточно говнокода...
- - - -
Как обычный файл мр3, даже иконка не будет меняться... Никакой дополн. инфы.
Аааа,интересно прост было)))как будет выглядеть мп3шка))
#9.
tipsun
Off
(19)
Moderator
2011.04.28 21:09
Выложил свой говноЛистингФайлов/папок...
Отредактировано tipsun (2011.04.28 21:09)
Хотел спросить, как сделать раздельно показ сначала папок потом файлов в определенной папке?
Я это представляю как отдельное условие :: if(is_dir()){} :: при сканирований папки. В один массив заносить имена папок, потом сортировать по имени. И массив с именами файлов сортировать по усм. пользователя. Потом всё это обьединить :: array_merge() :: и посчитать :: sizeof() ::
Поправил, слегка
Код:
span style="color: #0000BB"><?php !preg_match('/^[a-z0-9\_\-][a-z0-9\/\.\_\-]{1,}$/i', $_GET['dir']) ?> |
Ну хотел чтоб при вводе только '_', '/', '.' и т.д. тоже была типа ошибка. Правда после '/' не будет уже работать это правило... ну и ладно...
Переделал ::foreach:: на ::for::
Ну и реализовал показ сначала папок, потом файлов.
- - - -
Перезалил архив.
Отредактировано tipsun (2011.04.29 20:08)
сделай статистику сколько раз скачали файл))) например "Скачать(47раз)" ну как то так)))
Для этого надо отдельный файл писать (about.php к примеру), база (ну можно и файлами обойтись, но это совсем говнокод, вроде как).
- - - -
Сейчас старый говноЛистинг свой поковыряю, может и получится сделать...
Отредактировано tipsun (2011.04.29 21:09)
я думал это проще писать)))и желательно чтоб выводило возле названий папок сколько в них файлов как то так "Видео (1985)" ))))
Как сделать?
1) Сканировать только папку, и показывать сколько именно в ней файлов.
2) Сканировать папку и все находящиеся в ней папки, и показывать сколько всего файлов содержит данная папка. Нагружает сервер, если базу не использовать или мемкэш, которым я не умею пользоваться.
С базой можно типа сканировать, после занести в базу количество файлов и время, при истечении которого начнется повторное сканирование.
Отредактировано tipsun (2011.04.29 22:10)
2 вариант использовать только при условии что кол-во будет хранится отдельно в бд
Вот как
возможно будет выглядеть about.php
Отредактировано tipsun (2011.04.30 12:12)
Доделал примитивнейшую статистику...
Осталось функцию подсчета количества файлов в папке написать...
Когда-то писал, поэтому думаю не очень долго буду писать в этот раз
- - - -
ещё поправил извлечение расширения файла, оказывается это делается при помощи ::pathinfo()::
Отредактировано tipsun (2011.04.30 17:05)
Мда, как задумал не получилось, переделал на одну такую зафигулину... Потом узнаете/поржете
Ну мне эта идея кажется не плохой.
- - - -
Да ладно, чего говнокод таить
sys/funs.phpКод:
span style="color: #0000BB"><?phpdefine('TIMER', microtime(true));//...function html($body){exit('<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"><html><head><meta http-equiv="Cache-Control" content="no-cache" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="keywords" content="'.$_SERVER['HTTP_HOST'].'" /><title>'.$_SERVER['HTTP_HOST'].'</title><link rel="stylesheet" type="text/css" href="sys/default.css" /></head><body><div class="head">DOWNLOADS</div><div class="f1"></div><div class="f2"></div><div class="f3"></div><div class="f4"></div><div class="f5"></div>'.$body.'<div class="h1"></div><div class="h2"></div><div class="h3"></div><div class="h4"></div><div class="h5"></div><div class="foot">© <a href="/">Home</a> by TiPsun ('.round(microtime(true) - TIMER, 3).')</div><div class="f1"></div><div class="f2"></div><div class="f3"></div><div class="f4"></div><div class="f5"></div></body></html>');}?> |
При прямом выводе не работает header();
А так на 1 инклуд меньше... И вообще удобно вроде...
- - - -
Скоро выложу новую говноверсию...
Отредактировано tipsun (2011.05.01 14:02)
Подсчет хочу осуществить путем самописного класса... Если конечно получится написать этот класс.
Черт, надо было не так. А глобально... 1 раз просканировал и занес в базу все папки сразу.
- - - -
Не знаю как сделать, такой как есть класс оставлю...
Отредактировано tipsun (2011.05.01 20:08)
Фух
- - - -
Про "время актуальности" забыл... епт
- - - -
Поправил...
Код:
span style="color: #0000BB"><?php//вот для чего нужен был strpos($_GET['dir'], '/.');//чтоб не указывали ..... типа ?dir=_Kartinki/./././240x320//от остального прег_матч, чтоб в начале не указалвывали / или ./ т.д.//правда потом в папку нельзя будет назвать типа .olool т.к. olo/.ololo опознается как ошибкэ//потом в прием папки обязательно добавлюclass dirStat { function count($dir) { GLOBAL $db; $dir = preg_replace(array('/\/{2,}/', '/\/\.{1,}/'), array('/', null), $dir); $query = $db->prepare("SELECT `count` FROM `dirs` WHERE `name`=? AND `time`<'".$_SERVER['REQUEST_TIME']."' LIMIT 1;"); $query->execute(array($dir)); if($query->rowCount()) { return $query->fetchColumn(); } $this->count = 0; self::run($dir); $query = $db->prepare("REPLACE INTO `dirs` SET `name`=?, `count`='".$this->count."', `time`='".$_SERVER['REQUEST_TIME']."+600';"); $query->execute(array($dir)); return $this->count; } function run($dir) { if(is_dir('./'.$dir) and false !== ($opendir = opendir('./'.$dir))) { while(false !== ($unit = readdir($opendir))) { if('.' !== $unit and '..' !== $unit and 'about.php' !== $unit and 'index.php' !== $unit and 'sys' !== $unit and 'Thumbs.db' !== $unit) { if(is_dir('./'.$dir.'/'.$unit)) { self::run($dir.'/'.$unit); } else { $this->count += 1; } } } closedir($opendir); } return; } } $STAT = new dirStat;//использование...echo $STAT->count($dir);?> |
Отредактировано tipsun (2011.05.02 09:09)
Зря я делал '/' при получении каталога!
Подскажите пожалуйста, печально ли будет если я ограничу прием адреса папки до
Код:
span style="color: #0000BB"><?php !preg_match('/^[a-z0-9\_\-][a-z0-9\_\-\/]{1,}$/i', $_GET['dir'])) ?> |
. Точка все портит. Из-за нее приходится дополнительно лепить защиту.
Отредактировано tipsun (2011.05.02 09:09)
ну сам смотри, как папки называть будешь
Ну по-моему лучше сразу ограничить один раз прег_матчем чем потом везде на спец символы обрабатывать, точки учитывать... Если не учитывать, то в базу урл будет записываться с точками... Ну т.е. вроде одно и то же для ::is_dir():: , а в базу идет со всем этим мусором... /./././
этот мусор потом чистить... А так надо будет перед занесением только повторяющиеся слеши убрать.
Отредактировано tipsun (2011.05.02 09:09)
Как я запарился с этим говнозагрузником...
Дырку тоже закрыл. С ::$page:: связана была в index.php
- - - -
Добавил последнюю версию.
Посмотрите пожалуйста, кто не занят делом, если ли ошибки/дырки...
Отредактировано tipsun (2011.05.02 16:04)
ну по коду я незнаю,но так ошибок нету,считает норм))С такими темпами ты уже из зц напишешь полноценный загруз центр)))если будешь его еще дополнять чем-то,или делать его более крупным,то небольшая просьба,если можешь то сделай чтоб делало скрины с flesh а то сколько я смотрел зц,не один не делает скрины с flesh файлов)))))себе поставлю твой зц для картинок)))
Ну не знаю. Я оказывается неправильно код пишу.
Akdmeh отозвался на другом форуме, за что ему спасибо. Он написал, что у меня неправильный подход к построению кода.
Я теперь вообще растерян...
Отредактировано tipsun (2011.05.02 20:08)
Хорошо хоть мой говнокод пока никто не видит
Хочу попробовать написать загрузчик, который бы не относился к говнокоду.
Есть 2 мысли:
1) Читать прямо с папок, но кешировать страницы.
2) Читать с базы, может еще и кешировать страницы.
- - - -
Таблица с файлами и папками выглядит так:
+ еще может вес, скачиваний файла
+ для папок кол-во файлов/папок в ней
+ описание для папок, файлов
Функция сканирования выглядит так:
Но есть сомнения, стоит ли так делать, вдруг, как говориться, захочется что-то изменить.
Есть мысль сделать простую функцию, которая с нужной папки все просканирует и выдаст одномерный массив, после специальным классом или еще чем все элементы перебрать и установить параметры и прочее.
Код:
span style="color: #0000BB"><?phpclass Common { public static function dread($parent) { $array = array(); if (false != ($resource = opendir($parent))) { while (false != ($name = readdir($resource))) { if ('.' != $name && '..' != $name) { $child = $parent . '/' . $name; if (is_dir($child)) { $array += self::dread($child); $isDir = true; } $array[] = array( 'type' => (! $isDir), 'name' => $name, 'parent' => basename($parent), 'path' => $child, 'size' => $isDir ? 0 : filesize($child), 'extension' => $isDir ? null : pathinfo($name, PATHINFO_EXTENSION), 'visible' => true, 'description' => null, 'fixed' => null ); } } closedir($resource); } return $array; }} |
Добавлено спустя 5 минут 29 секунд: Может стоит сделать как на форуме, после того, как просканировал, переименовывать файл в <md5>.ext чтоб вести статистику скачиваний итд. А еще есть и ссылки =/
такое ощущение, что ты эту табличку из sea брал. необходимо еще хранить id родительской категории.
Я заглядывал в sea, но базу я вроде не смотрел. И то я заглядывал, чтоб посмотреть как там сканирование идет.
Добавлено спустя 1 минуту 41 секунду: Gemorroj написал:
необходимо еще хранить id родительской категории.
Ох, ну озадачил, так озадачил. =/
Добавлено спустя 9 минут 16 секунд: Да, а то такая же папка может быть в другой категории и получится каша.
Вот выдал мой мозг загагулину, не уверен что верно.
Код:
span style="color: #0000BB"><?phpfunction dread($parent, $childId = 0, $parentId = 0) { $query = null; if (false != ($resource = opendir($parent))) { while (false != ($name = readdir($resource))) { if ('.' != $name && '..' != $name) { $child = $parent . DIRECTORY_SEPARATOR . $name; $childId += 1; $query .= (is_file($child) ? '' : '>>>') . 'VALUES(`id`=\'' . $childId . '\', `parent_id`=\''.$parentId.'\', `type`=\''.(is_file($child) ? 1 : 0).'\', `name`=\''.$name.'\', `path`=\''.$child.'\'), ' . PHP_EOL; if (is_dir($child)) { $result = dread($child, $childId, $childId); $query .= $result[0]; $childId = $result[1]; } } } closedir($resource); } return array($query, $childId);} |
Добавлено спустя 9 минут 58 секунд: Правда существующие записи придется удалять. А так больше мыслей нет, пока что.
Тут еще проблема, что при большом кол-ве файлов, получится огромный SQL запрос. А в MySQL есть ограничение на максимальную длину пакета. Не помню сколько там по умолчанию уже, но упереться в нее можно вполне элементарно, я уприался. Т.к. не всегда есть возможность переконфигурять настройки mysql сервера, нужно разбивать большие запросы на несколько частей.
Добавлено спустя 15 секунд: https://dev.mysql.com/doc/refman/5.5/en … large.html
Gemorroj, да это вообще мелочи.
- - - -
Я вот что забыл - возвращать счетчик надо, а то нехорошо получается.
- - - -
Но спасибо за инфу
Разбить можно ориентируясь на запятая + перенос.
- - - -
Либо сделать массив строк, и их объединять в кол-ве 15-20 например.
Добавлено спустя 4 минуты 10 секунд: Но это все говнокод, ибо прежние записи не будут иметь смысла.
Кто-то сохранит ссылку на файл, а он уже удален, либо попадет на другой файл.
Привел в порядок набросок:
Код:
span style="color: #0000BB"><?phpfunction dread($parent, $cid = 0) { $pid = $cid; $values = null; if (false != ($resource = opendir($parent))) { while (false != ($name = readdir($resource))) { if ('.' != $name && '..' != $name) { $child = $parent . DIRECTORY_SEPARATOR . $name; $type = filetype($child); $size = 'file' == $type ? filesize($child) : 0; $values .= sprintf( "('%d', '%d', '%s', '%s', '%d', '%s'),\r\n", ++$cid, $pid, $type, $name, $size, $child ); if ('dir' == $type) { $result = dread($child, $cid); $values .= $result[0]; $cid = $result[1]; } } } closedir($resource); } return array($values, $cid);} |
tipsun, в данном случае (InnoDB) можно вообще, на каждый файл делать отдельный инсерт и просто обернуть цикл в транзакцию. И еще использовать PDO с подготовленным вне цикла запросом.
Короче, я не на правильном пути...
Заглянул в sea_downloads2, там попроще, без id. Все на путях.
ПонЭл принцип, как у меня это все будет.
Сканировать и сверять так же буду, как в sea, а насчет добавления, там будет принцип лесенки.
Самое главное, чтоб получилась эта лесенка, чтоб плавная была.
Остальное за pdo->lastinsertid(). Дальше мысля пока не пошла.
Добавлено спустя 3 минуты 58 секунд: Еще понял, что надо бы полный путь сразу указывать, чтоб потом не мучаться. Отдавать все-равно буду через одну точку, значит локального пути хватит вполне.
Добавлено спустя 9 минут 59 секунд: Можно даже без pdo->lastinsertid, ибо по принципу лесенки, эта папка уже будет в базе.
Значит я могу запросом вытащить id который будет parent_id для следующих элементов.
tipsun, в sea далеко не идеальная архитектура. Принимать ее как эталонную не стоит.
Можно было бы одной функцией попробовать, типа: сравнить два массива и выдать только недостающие ключи. А там перебор идет.
Можно 1 циклом обойтись, в функцию подготовленный prepare запихать и вперед.
- - - -
Надо еще с путями разобраться и parent_id
Код:
span style="color: #0000BB"><?phpfunction dread($parent) { $array = array(); if (false !== ($resource = opendir($parent))) { while (false !== ($name = readdir($resource))) { if ('.' != $name && '..' != $name) { $child = $parent . DIRECTORY_SEPARATOR . $name; $array[] = $child; if (is_dir($child)) { $array = array_merge($array, dread($child)); } } } closedir($resource); } return $array;}// Get physical pathes$root = realpath('folders');$physical = dread($root);// Get virtual pathes$virtual = array();$pdo = new Pdo('mysql:dbname=downloads;host=127.0.0.1;', 'root', '');$qt = 'SELECT `path` FROM `downloads`;';if (false !== ($q = $pdo->query($qt))) { if ($q->rowCount()) { $virtual = $q->fetchAll(PDO::FETCH_COLUMN); }}// Search new and invalid pathes$new = array_diff($physical, $virtual);// $invalid = array_diff($virtual, $physical);// Add new pathes in virtual$qt = 'INSERT INTO `downloads` (`path`, `name`, `type`, `parent_id`, `size`) ' . 'VALUES (:path, :name, :type, :parent_id, :size)';$pdo->beginTransaction();$q = $pdo->prepare($qt);foreach ((array) dread($root) as $path) { $q->execute(array( ':path' => $path, ':name' => basename($path), ':type' => ($type = filetype($path)), ':parent_id' => 0, ':size' => ('file' == $type ? filesize($path) : 0) ));}$pdo->commit(); |
Отредактировано tipsun (2013.02.01 12:12)
tipsun, да, мне видится такой более чистым и правильным. Единственное что, нужно бы еще проверку на false делать более жесткой. Т.е.
!==
Спасибо, что посмотрел.
Я вот еще не пойму пока, мне полный путь нужен в базе или нет.
Еще вот никак не представлю как parent_id узнавать.
Добавил
#48.
Думаю так попроще будет.
УРА!!!
Код:
span style="color: #0000BB"><?phpfunction dread($parent) { $array = array(); if (false !== ($resource = opendir($parent))) { while (false !== ($name = readdir($resource))) { if ('.' != $name && '..' != $name) { $child = $parent . DIRECTORY_SEPARATOR . $name; $array[] = $child; if (is_dir($child)) { $array = array_merge($array, dread($child)); } } } closedir($resource); } return $array;}// Get physical pathes$root = realpath('files');$physical = dread($root);if (! empty($physical)) { // Get virtual pathes $virtual = array(); $pdo = new Pdo('mysql:dbname=downloads;host=127.0.0.1;', 'root', ''); $qt = 'SELECT `id`, `path` FROM `downloads`;'; if (false !== ($q = $pdo->query($qt))) { if ($q->rowCount()) { while ($path = $q->fetch(PDO::FETCH_ASSOC)) { $virtual[$path['id']] = $path['path']; } } } // Search new pathes $new = empty($virtual) ? $physical : array_diff($physical, $virtual); // Search invalid pathes // $invalid = array_diff($virtual, $physical); if (! empty($new)) { // Add new pathes on virtual $qt = 'INSERT INTO `downloads` (`path`, `name`, `type`, `parent_id`, `size`) ' . 'VALUES (:path, :name, :type, :parent_id, :size);'; $pdo->beginTransaction(); $q = $pdo->prepare($qt); $parentId = null; foreach ($new as $path) { if (false !== $q->execute(array( ':path' => $path, ':name' => basename($path), ':type' => ($type = filetype($path)), ':parent_id' => (int) array_search(dirname($path), $virtual), ':size' => ('file' == $type ? filesize($path) : 0) ))) { $parentId += (null === $parentId) ? $pdo->lastInsertId('downloads') : 1; if ('dir' == $type) { // $virtual[$pdo->lastInsertId('downloads.id')] = $path; $virtual[$parentId] = $path; } } } $pdo->commit(); }} |
Я еще думал может ключи и значения после
отсеивания array_diff() местами поменять,
чтоб по ключу можно было получить parent_id,
чем искать array_search()?
Вот, заоптимизировал, вроде. Хотя кто знает, может простым: $pdo->lastInsertId('downloads') было бы куда быстрее.
Пост
#52
Насчет физически несуществующих файлов, можно в принципе оставить эти записи.
Просто, если человек наткнется, то проверить один раз на существование файла/папки, если нет, то удалить все вложенные папки/файлы.
Отредактировано tipsun (2013.02.01 22:10)
Если код плохой, есть еще одна мысль.
Получить сначала виртуальные данные, потом при проверке физических данных сразу все фиксировать.
Чтобы получилась кнопка [ .. ]
После в отдельную переменную и долой с массива.
Я, наверно, нативным синтаксисом в шаблонах, на CodeIgniter попробую все написать.
Есть желающие присоединиться к написанию?
Если да, то я на code.google.com выложу.
Пока что только CodeIgniter залил. Пока с ним разберусь много времени уйдет...
Залил немного своего кода.
Добавлено спустя 1 минуту 3 секунды: Не знаю как там драйвер переключить на pdo. В настройках если переключить, то ошибка получается.
Gemorroj, спс.
Сейчас попытаюсь сделать.
А стоит ли мне вообще делать это зц на фреймворке?
Добавлено спустя 5 минут 42 секунды: Есть молодой фреймворк "Phalcon". Может на нем лучше, или проще. Или вообще без фреймворка.
tipsun, Phalcon означает, что на говнохостингах работать оно не будет. Если ты изначально определяешь, что работать будет только на VDS или выше, где можно поставить нужные PECL модули, то можно попробовать.
Спс. Надо будет тогда просто этот фреймворк изучить.
Останусь пока тогда на CI.
Новый адрес хранилища. С прежним что-то случилось. Я не стал заморачиваться и по-новой создал.
Теперь там только модули будут к Yii.
Наконец разобрался в этом Yii чпу rules.
Сделал, по подсказке друга, при помощи CActiveDataProvider, все.
Буквально пару строк кода и "вуаля".
сравниваю с роутами симфони2
Код:
test_json: |
pattern: /test/{type}/{filter}/json |
defaults: { _controller: WapinetTestBundle:Test:indexJson, _format: json, type: test, filter: all } |
requirements: |
_scheme: https |
type: test|prod |
filter: all|old|new |
надеюсь по синтаксису понятно, что там происходит. По-моему у симфони2 роуты покрасивее
Так вроде бы немного понятно.
Сейчас у меня такое правило для модуля:
- - - -
Прописывать я научился, а вот ссылки создавать пока не получается нормально.
Реализовал правильные ссылки. Вроде.