<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Антон Шевчук &#187; Estimation</title>
	<atom:link href="http://anton.shevchuk.name/category/estimation/feed/" rel="self" type="application/rss+xml" />
	<link>http://anton.shevchuk.name</link>
	<description>Web-разработчик</description>
	<lastBuildDate>Wed, 01 Feb 2012 12:54:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>ТЗ для web-разработчика</title>
		<link>http://anton.shevchuk.name/estimation/tz-for-web-developer/</link>
		<comments>http://anton.shevchuk.name/estimation/tz-for-web-developer/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 10:19:40 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[Estimation]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=246</guid>
		<description><![CDATA[Написание хорошего ТЗ для разработки сайта еще та проблема, и я поделюсь своим опытом по созданию &#8220;человеко-понятного&#8221; описания для заказчика для разработчика. Начну из далека, не судите строго&#8230; Шаг ноль. Заказчик. Манипулирование. Начнем с первой встречи с заказчиком. Произвести впечатление серьезного человека, с которым можно и нужно работать &#8211; вот Ваша основная задача &#8211; так [...]]]></description>
			<content:encoded><![CDATA[<p align="center"><img src="http://anton.shevchuk.name/wp-content/uploads/2008/03/030508-1623-1.jpg" alt="" title="Time-is-Money" /></p>
<p>Написание хорошего ТЗ для разработки сайта еще та проблема, и я поделюсь своим опытом по созданию &#8220;человеко-понятного&#8221; описания <strike>для заказчика</strike> для разработчика.<br />
<span id="more-246"></span><br />
Начну из далека, не судите строго&#8230;</p>
<h2>Шаг ноль. Заказчик.</h2>
<h3>Манипулирование.</h3>
<p>Начнем с первой встречи с заказчиком. Произвести впечатление серьезного человека, с которым можно и нужно работать &#8211; вот Ваша основная задача &#8211; так что отложите Ваш любимый костюм цвета хаки &#8211; джинсы и рубашечка &#8211; будет самое оно.<br />
Место встречи тоже очень важно &#8211; MacDonalds &#8211; не лучший выбор &#8211; лично я выбираю кофейни &#8211; тихая спокойная обстановка распологает к продуктивной беседе. Кстати &#8211; тут Вам и первый звоночек &#8211; если заказчик угощает &#8211; это хорошо, иначе &#8211; работайте по предоплате.<br />
На этой первой встречи Вы должны убедить заказчика в том, что из Вас двоих именно Вы профессионал, и именно Вы знаете чего он хочет. Берите инициативу на себя во время деловых встреч и переговоров. Не стесняйтесь давать подсказки заказчику, приводите примеры, но только такие какие Вам нравятся, и Вам они выгодны (к примеру лежит у Вас в заначке готовый сайтец). Не дело если заказчик сядет Вам на голову &#8211; может он где-то и директор, но только не с Вами &#8211; для Вас он просто один из многих.</p>
<h3>Аналоги.</h3>
<p>Добейтесь от заказчика аналогов его детища (я сильно сомневаюсь в уникальности идеи, такие встречаются крайне редко), так вы быстрее поймете суть того чего от вас добиваются. Очень хорошо если у Вас есть ноут с доступом в и-нет, и Вы сможете все сразу посмотреть. (раскошельтесь на PCMCIA GSM модем &#8211; это производит впечатление).</p>
<h3>Деньги.</h3>
<p>Тут нужно быть очень внимательным &#8211; Вы должны точно понять и уяснить каким образом проект будет зарабатывать (пусть и в перспективе). Понятно, что на сайты-визитки это не распространяется.</p>
<h3>ТЗ.</h3>
<p>Во время разговора записывайте важные моменты &#8211; не надейтесь на память &#8211; обязательно проколитесь. Если у Вас возникают вопросы &#8211; задавайте их, ответы опять же стоит записывать. По окончанию беседы перед Вами должен лежать черновик ТЗ.</p>
<p>А теперь наступает самый трудный момент &#8211; Вы должны убедить заказчика в том, что именно Вы пишите ТЗ, и он за него должен заплатить. Если таковое не получилось &#8211; пришлите ему образец &#8211; пусть помучается, в итоге, если он ценит своё время &#8211; он таки согласиться на Ваши услуги.</p>
<h2>Шаг первый. ТЗ.</h2>
<h3>Писательство.</h3>
<p>Перед началом работы над ТЗ Вы должны твердо уяснить для себя &#8211; данный документ должен трактоваться однозначно не только Вами и заказчиком, но и любым другим разработчиком, и это достаточно сложная задача.</p>
<p>Небольшое лирическое отступление в начали пути &#8211; имхо, считаю что одно из самых правильных способов подачи информации есть графический, т.е. лучше один раз увидеть, чем сто раз услышать. Так что будем рисовать макеты (mock-up&#8217;ы) страниц &#8211; для этого подойдет даже MS Word (хотя конечно лучше воспользоваться чем-то вроде <a href="http://www.axure.com/">Axure RP Pro</a>):</p>
<blockquote><p>В качестве подопытного возьмем сайт представляющий собой доску объявлений по купле-продаже автомобилей.</p></blockquote>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2008/07/main-page.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2008/07/main-page-300x220.png" alt="" title="main-page" width="300" height="220" class="alignnone size-medium wp-image-249" /></a></p>
<p>Как Вы видите &#8211; это главная страница сайта, на ее &#8220;рисование&#8221; у меня ушло чуть меньше 5-ти минут, теперь можно попробовать описать словами:</p>
<blockquote><p>Сверху должен располагаться логотип, правее форма для авторизации пользователей, чуть ниже логотипа &#8211; ссылки сайта, под ссылками &#8211; топ комментируемых новостей, и еще ниже блок рекламы. По центру должна находиться форма поиска, под ней &#8211; последние добавленные объявления, затем блок рекламы, и последние новости. Под формой авторизации должен располагаться блок с последними комментариями на форуме, и ниже блок рекламы. В самом низу страницы будут находиться счетчики-пузомерки, а так же копирайты</p></blockquote>
<p>Ух, описание конечно &#8211; много буков, и много вопросов, макетик более однозначный. Ладно поехали дальше, ближе к сути.</p>
<p>Для начала необходимо выделить сущности, роли пользователей и определить уровни доступа (буду краток &#8211; приведу таблицу):</p>
<table border="1" cellspacing="1" width="100%">
<tr>
<th>  Роль/Сущность  </th>
<th>  Пользователь  </th>
<th>  Объявления  </th>
<th>  Комментарии к  объявлениям  </th>
<th>  Новости  </th>
<th>  Комментарии к  новостям  </th>
</tr>
<tr>
<th>  Гость  </th>
<td align="center">  регистрация  </td>
<td align="center">  R  </td>
<td align="center">  R,W*  </td>
<td align="center">  R  </td>
<td align="center">  R,W*  </td>
</tr>
<tr>
<th>  Пользователь  </th>
<td align="center">  E*  </td>
<td align="center">  R,W  </td>
<td align="center">  R,W  </td>
<td align="center">  R  </td>
<td align="center">  R,W  </td>
</tr>
<tr>
<th>  Администратор  </th>
<td align="center">  X  </td>
<td align="center">  M  </td>
<td align="center">  M  </td>
<td align="center">  X  </td>
<td align="center">  M  </td>
</tr>
</table>
<p>Где:</p>
<ul>
<li>R &#8211; чтение</li>
<li>W &#8211; создание</li>
<li>E &#8211; редактирование</li>
<li>X &#8211; полный доступ (создание/редактирование/удаление)</li>
<li>M &#8211; модерирование (редактирование/удаление)</li>
<li>* &#8211; особенности реализации отображены в документации</li>
</ul>
<p>Теперь перед нами стоит следующая задача:</p>
<ul>
<li>Для всех <strong>R</strong> &#8211; создать макеты страниц</li>
<li>Для всех <strong>W</strong>, <strong>E</strong> &#8211; описать полностью формы &#8211; т.е. какие поля редактируемы, и по каким правилам</li>
<li>Для всех <strong>X</strong>, <strong>M</strong> &#8211; mock up&#8217;ы страниц с навигацией + формы создания/редактирования</li>
</ul>
<p>Начнем с простого &#8211; <strong>R</strong> &#8211; для объявлений:</p>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2008/07/advertisement.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2008/07/advertisement-300x173.png" alt="" title="advertisement" width="300" height="173" class="alignnone size-medium wp-image-279" /></a></p>
<p>И для новостей:<br />
<a href="http://anton.shevchuk.name/wp-content/uploads/2008/07/news.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2008/07/news-300x172.png" alt="" title="news" width="300" height="172" class="alignnone size-medium wp-image-280" /></a></p>
<p>Далее приведу пример описание формы для комментариев (<strong>W</strong>):</p>
<ul>
<li>Имя – буквы кирилицы и латиницы, цифры, символ подчеркивания и дефис, обязательное</li>
<li>E-mail &#8211; в соответствии со стандартом <a href="http://tools.ietf.org/html/rfc2822">RFC-2822</a>, обязательное</li>
<li>Ссылка на Сайт &#8211; в соответствии со стандартом <a href="http://tools.ietf.org/html/rfc2616">RFC-2616</a></li>
<li>Текст – непустое поле больше 3-х не пробельных символов</li>
<li><a href="http://ru.wikipedia.org/wiki/Captcha">CAPTCHA</a> &#8211; тест Тьюринга для защиты от спама, обязательное</li>
</ul>
<p>И соответствующий mock up:<br />
<a href="http://anton.shevchuk.name/wp-content/uploads/2008/07/comments.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2008/07/comments-300x100.png" alt="" title="comments" width="300" height="100" class="alignnone size-medium wp-image-282" /></a></p>
<p>Как видите &#8211; подобные макеты достаточно информативны, а так же подготавливают заказчика к будущему продукту. </p>
<p>Так же не забудьте приготовить шаблоны писем (вот вам примерчик):<br />
<a href="http://anton.shevchuk.name/wp-content/uploads/2008/07/letter.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2008/07/letter-300x78.png" alt="" title="letter" width="300" height="78" class="alignnone size-medium wp-image-277" /></a></p>
<p>Еще пригодится диаграмма прецедентов (вполне вероятно, Вы могли её нарисовать еще на этапе обсуждения проекта с заказчиком):</p>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2008/07/uml.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2008/07/uml-231x300.png" alt="" title="uml" width="231" height="300" class="alignnone size-medium wp-image-273" /></a></p>
<h3>Проектирование архитектуры и БД.</h3>
<p>Почему я включил сюда этот пункт? Всё очень просто &#8211; по своему опыту скажу &#8211; когда документация по проекту заходит в отдел и начинается разработка архитектуры и БД, то возникает очень много вопросов, о которых даже мысли не возникало при прочтении доки. В итоге проектная команда простаивает, пока менеджер, краснее перед заказчиком, выясняет эти нюансы. Было бы намного логичнее быть на шаг впереди, и набросать архитектуру и БД уже на этом этапе &#8211; это часа 3-4 работы, которая сможет сэкономить и время, и деньги, и нервы (конечно архитектура в таком варианте будет слишком сыра, но уже сможет выявить несколько подводных камней).</p>
<p>Архитектуру я описывать не буду &#8211; так как в данном примере особо и проектировать нечего, а low-level нам продиктует фреймворк. </p>
<p>А вот приблизительный набросок БД это всегда пожалуйста (опять же особо не заморачиваясь на подробности):<br />
<a href="http://anton.shevchuk.name/wp-content/uploads/2008/07/db.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2008/07/db-263x300.png" alt="" title="db" width="263" height="300" class="alignnone size-medium wp-image-288" /></a></p>
<h2>Шаг второй. Оценка проекта.</h2>
<p>О данном этапе советую прочитать статью &#8220;<a href="http://anton.shevchuk.name/estimation/estimation-for-beginners/">Оцениваем проекты</a>&#8221; (правда, я скромный?)</p>
<h2>Вывод</h2>
<p>Я очень надеюсь, что данная статья поможет Вам избежать ошибок на первом этапе жизни проекта, зачастую именно недопонимание разработчиком ТЗ по проекту ведет к увеличению стоимости разработки, затягиванию сроков, а так же к более серьезным последствиям&#8230;</p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li>No Related Post</li></ul>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/estimation/tz-for-web-developer/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Оцениваем проекты</title>
		<link>http://anton.shevchuk.name/estimation/estimation-for-beginners/</link>
		<comments>http://anton.shevchuk.name/estimation/estimation-for-beginners/#comments</comments>
		<pubDate>Wed, 05 Mar 2008 16:23:33 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[Estimation]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/estimation/estimation-for-beginners/</guid>
		<description><![CDATA[Одной из основных моих активностей на работе является оценка проектов. И в данной статье я постараюсь поделиться своим опытом в данной области. По данной теме написано очень много книг и статей, но зачастую все примеры из них описывают многомиллионные проекты расчитанные на несколько лет, и адаптировать их под нужды небольших проектов до 1000 часов довольно [...]]]></description>
			<content:encoded><![CDATA[<p align="center"><img  src="http://anton.shevchuk.name/wp-content/uploads/2008/03/030508-1623-1.jpg" alt=""/></p>
<p>Одной из основных моих активностей на работе является оценка проектов. И в данной статье я постараюсь поделиться своим опытом в данной области.<br />
<span id="more-169"></span><br />
По данной теме написано очень много книг и статей, но зачастую все примеры из них описывают многомиллионные проекты расчитанные на несколько лет, и адаптировать их под нужды небольших проектов до 1000 часов довольно проблематично, для таких проектов необходима &#8220;экспертная&#8221; оценка &#8211; т.е. оценка человека, который знаком с технологиями и разрабатывал или рукводил разработкой подобных проектов. И так предположим, что Вы и есть тот самый человек, кому прийдется оценивать проект.</p>
<p>Дабы не ходить вокруг да около, лучше всего будет привести пример, поэтому возьмем абстрактный проект со следующими мутными требованиями:</p>
<p>&#8220;Хочу сайт, где пользователи смогут писать посты с картинками, оставлять комментарии, выставлять рейтинги, обмениваться сообщениями, а так же на сайте будет магазин с книгами, книги будет добавлять администратор сайта, он так же будет следить за порядком на сайте. Сайт должен иметь &#8220;лёгкий&#8221; дизайн и соответствовать web 2.0&#8243;</p>
<p>Начнем по порядку:</p>
<ol>
<li>Пытаемся понять бизнес-идею заказчика, если у Вас это не получилось &#8211; необходимо добиться этого понимания, глядя на данное описание можно предположить 2 варианта для получения отдачи с сайта &#8211; процент с продажи книг и контекстная реклама (о которой не было сказано ни слова, но очень часто предполагается по умолчанию)</li>
<li>Задайте следующие вопросы заказчику:
<ul>
<li>Какие нагрузочные требования к системе, сколько будет зарегистрированных пользователей, сколько онлайн (я сомневаюсь, что заказчик адекватно поймет словосочетание &#8220;конкурирующие запросы&#8221;)?</li>
<li>Нужна ли поддержка мультиязычности?</li>
<li>В каких браузерах должен корректно отображаться сайт?</li>
<li>Какие требования к безопасности сайта (понятно, что мы не будем писать дырявое приложение, но лучше заранее знать что сайт будет работать по HTTPS и URL будут уникальны для каждого пользователя)</li>
</ul>
</li>
<li>Разбейте проект на составляющие &#8211; составьте фиче-лист проекта</li>
<li>Все вопросы которые возникают &#8211; записываем, и не забываем задать их заказчику, каждый вопрос желательно сопровождать пояснениями, дабы не смущать заказчика, а так же не мешало бы подталкивать его к правильному ответу, который бы минимизировал часть рисков (к примеру на вопрос о поддержке различных браузеров, лучше упомянуть, что самые популярные нынче это IE6.0+, FF 2.0+ и Safari 3.0+, иначе есть риск, что придется подгонять дизайн под какие-нить ископаемые, типа Netscape 8.0)</li>
<li>Итоговую оценку с подробными комментариями и вопросами отсылаем заказчику в формате XLS &#8211; пусть он сам попробует добавить/убрать некоторые пункты</li>
</ol>
<p>Составление фиче-листа</p>
<p>Данный пункт требует определенных навыков, дабы расшифровать требования и ничего не упустить, и вот некоторые советы по составлению фиче-листа:</p>
<ol>
<li>Каждый пункт должен включать 2 оценки &#8211; среднюю, и максимальную (это если сработают все риски, риски лучше сразу описывать)</li>
<li>Выделите следующие части в отдельные пункты
<ul>
<li>разработка и внедрение дизайна</li>
<li>разработка архитектуры системы</li>
<li>разработка БД</li>
<li>анализ требований (собственно это чем вы будете заниматься до старта проекта, включая написания документации)</li>
<li>если у Вас команда разработчиков, то так же должен быть пункт &#8220;Передача знаний&#8221; &#8211; это время на митинги, и тому подобные рабочие процессы, которые кушают бюджет</li>
<li>менеджмент &#8211; включает в себя общение с заказчиком и сам менеджмент как таковой</li>
<li>тестирование &#8211; нам же нужна &#8220;живая&#8221; система</li>
<li>деплоймент системы на сервер заказчика</li>
</ul>
</li>
<li>Выделите отдельным пунктом &#8220;бесплатный сыр&#8221; &#8211; то что Вы бы сделали, даже если бы не было такого требования, к примеру &#8211; интеграция WYSIWYG редактора или поддержка User Friendly URL, интеграция Google Analytics и Google AdSense</li>
</ol>
<p>А теперь попытаемся выделить основные пункты из нашего &#8220;описания&#8221;:</p>
<ol>
<li>Обычное явление для сайта &#8211; присутствие страниц со статической информацией, которая может изменятся администратором, по личному опыту &#8211; для 90% сайтов необходимо было реализовывать данный функционал</li>
<li>У нас на сайте присутствует как минимум 3 роли : гость, зарегистрированный пользователь, администратор, а может еще будет модератор?</li>
<li>У нас есть как минимум 5 сущностей кроме пользователей: книги, посты, комментарии и рейтинги, а так же сообщения для приватных бесед, если чуть-чуть подумать, то появляются еще категории для книг и тэги для постов (дабы следовать web 2.0), необходимо все предположения уточнить у заказчика.</li>
<li>Дизайн аля web 2.0 может оказаться и с flash&#8217;ом или заказчик видел где-то, что-то и он хочет подобное, так что продолжаем формировать список вопросов</li>
<li>Если у нас электронный магазин, предполагается ли интеграция payment gateway&#8217;ев, если да, то каких.</li>
<li>Обмен сообщениями между пользователями &#8211; тоже довольно скользкий момент, возможно заказчик имеет ввиду чат, или всё же простенькую систему внутренних сообщений? Пользователи могут отсылать сообщения любому другому пользователю, или будет список друзей?</li>
</ol>
<p>Промежуточный фиче-лист включает в себя следующие пункты:</p>
<ul>
<li>Entities:
<ul>
<li>Static Pages</li>
<li>Users</li>
<li>Users Friends</li>
<li>Blog Posts</li>
<li>Blog Posts Tags</li>
<li>Blog Rates</li>
<li>Blog Comments</li>
<li>Books</li>
<li>Books Categories</li>
<li>Messages</li>
</ul>
</li>
<li>Free Section
<ul>
<li>User Friendly URL</li>
<li>WYSIWYG Editor</li>
<li>Google Analytics</li>
<li>Google AdSense</li>
</ul>
</li>
<li>Design</li>
<li>Architecture</li>
<li>Database Architecture</li>
<li>Knowledge transfer</li>
<li>Management</li>
<li>Testing</li>
<li>Deployment</li>
</ul>
<p>Далее лучше всего разбить данный список по ролям (гость, пользователь, администратор), а для таких пунктов как менеджмент, тестирования, анализ требований и передача знаний оценка будет указана в процентах от общего времени разработки, на данный момент это 10% для менеджмента, 30% для базового тестирования и по 5% на анализ и передачу знаний (такие значения выведены личным опытом и здравым смыслом).</p>
<p>В итоге у меня получился <a href='http://anton.shevchuk.name/wp-content/uploads/2008/03/estimation_template.zip' title='Estimation template'>фиче-лист</a> с очень приблизительной оценкой, впрочем описание тоже не радует деталями. В действительности после выяснений всех деталей, может оказаться, что заказчик хотел всего лишь что-то наподобие WordPress MU, а магазин представлял бы всего-лишь &#8211; ссылки на Amazon с указанием реферала, хотя, с таким же успехом, заказчик может хотеть и социальную сеть, со всеми соответствующими атрибутами&#8230;</p>
<p>Если Вам интересна данная тема, могу посоветовать прочитать еще статейку <a href="http://anton.shevchuk.name/php/php-cookbook-myphptubecom-en/">о клоне YouTube</a>.</p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li>No Related Post</li></ul>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/estimation/estimation-for-beginners/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Carnegie Mellon. Project Estimation Certificate</title>
		<link>http://anton.shevchuk.name/my-life/carnegie-mellon-project-estimation-certificate/</link>
		<comments>http://anton.shevchuk.name/my-life/carnegie-mellon-project-estimation-certificate/#comments</comments>
		<pubDate>Mon, 20 Aug 2007 10:38:58 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[Estimation]]></category>
		<category><![CDATA[My Life]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/my-life/carnegie-mellon-project-estimation-certificate/</guid>
		<description><![CDATA[Вот он какой: Теперь я &#8220;сертифицированный специалист по оценке проектов&#8221; :) Я знаю &#8220;Rough order of magnitude&#8221;, &#8220;Large Scale Analogy&#8221;, &#8220;WideBand Delphi&#8221;, &#8220;Wild Altogether Guess&#8221;, &#8220;SLIM&#8221; и много других страшных слов, но гвоздь программы &#8211; это COCOMO II (COnstructive COst Model) &#8211; с этим зверем мне любая оценка по зубам. В теории конечно, на практике [...]]]></description>
			<content:encoded><![CDATA[<p>Вот он какой:</p>
<p align='center'><a href='http://anton.shevchuk.name/wp-content/uploads/2007/08/carnegie_mellon.png' title='Carnegie Mellon. Project Estimation Certificate'><img src='http://anton.shevchuk.name/wp-content/uploads/2007/08/carnegie_mellon.thumbnail.png' alt='Carnegie Mellon. Project Estimation Certificate' /></a></p>
<p>Теперь я &#8220;сертифицированный специалист по оценке проектов&#8221; :)</p>
<p>Я знаю &#8220;Rough order of magnitude&#8221;, &#8220;Large Scale Analogy&#8221;, &#8220;WideBand Delphi&#8221;, &#8220;Wild Altogether Guess&#8221;, &#8220;SLIM&#8221; и много других страшных слов, но гвоздь программы &#8211; это COCOMO II (COnstructive COst Model) &#8211; с этим зверем мне любая оценка по зубам. </p>
<p>В теории конечно, на практике пока COCOMO еще не использовал, всё как-то больше применяю экспертную оценку, а времени на параллельную оценку, к сожалению, нету&#8230;</p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li>No Related Post</li></ul>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/my-life/carnegie-mellon-project-estimation-certificate/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP CookBook: MyPHPTube.com (клонируем YouTube)</title>
		<link>http://anton.shevchuk.name/php/php-cookbook-myphptubecom/</link>
		<comments>http://anton.shevchuk.name/php/php-cookbook-myphptubecom/#comments</comments>
		<pubDate>Mon, 02 Jul 2007 16:53:03 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[Estimation]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB 2.0]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/php/php-cookbook-myphptubecom-en/</guid>
		<description><![CDATA[С возросшей популярностью сервиса YouTube.com многим захотелось организовать подобный сервис, но как это сделать? Приведу небольшой рецепт организации такого сервиса. Функциональность Для начала опишем основной функционал сайта (сразу определимся и с ролями пользователей): Гость просмотр видеофайлов на сайте Пользователь аплоад видеофайлов Администратор управление пользователями управление файлами WEB 2.0 фичи А теперь расширем наш базовый функционал, [...]]]></description>
			<content:encoded><![CDATA[<p align='center'><img src='http://anton.shevchuk.name/wp-content/uploads/2007/07/myphptube.png' alt='MyPHPTube' /></p>
<p>С возросшей популярностью сервиса <a href="http://youtube.com"  target="_blank" title="http://youtube.com"  rel="nofollow">YouTube.com</a> многим захотелось организовать подобный сервис, но как это сделать? Приведу небольшой рецепт организации такого сервиса.</p>
<p><span id="more-101"></span></p>
<h2>Функциональность</h2>
<p>
Для начала опишем основной функционал сайта (сразу определимся и с ролями пользователей):
</p>
<ol>
<li> Гость
<ul>
<li> просмотр видеофайлов на сайте
</li>
</ul>
</li>
<li> Пользователь
<ul>
<li> аплоад видеофайлов
</li>
</ul>
</li>
<li> Администратор
<ul>
<li> управление пользователями
</li>
<li> управление файлами
</li>
</ul>
</li>
</ol>
<h2>WEB 2.0 фичи</h2>
<p>
А теперь расширем наш базовый функционал, чтобы привлечь аудиторию:
</p>
<ol>
<li> Гость
<ul>
<li> просмотр комментариев к видеофайлам
</li>
<li> поиск файлов (по категории, по тегам)
</li>
</ul>
</li>
<li> Пользователь
<ul>
<li> возможность оставлять комментарии к видеофайлам
</li>
<li> возможность записывать видеофайлы с web-камеры
</li>
<li> возможность связывать видеоролик с категорией
</li>
<li> возможность связывать видеоролик с несоклькими тегами (tags)
</li>
<li> выставление рейтинга видеофайла
</li>
<li> организация списка друзей
</li>
<li> внутренняя mail система
</li>
<li> закладки
</li>
</ul>
</li>
<li> Администратор
<ul>
<li> управление комментариями
</li>
<li> управление категориями
</li>
</ul>
</li>
</ol>
<p>Это конечно не весь функционал YouTube, но ведь нужно с чего-то начинать</p>
<h2>Конфигурация сервера</h2>
<p>Наша система будет базироваться на <acronym title="Linux Apache MySQL PHP">LAMP</acronym>:
</p>
<ul>
<li><strong>L</strong>inux</li>
<li><strong>A</strong>pache (версия 2.2 и выше)</li>
<li><strong>M</strong>ySQL (версия 5.0 и выше)</li>
<li><strong>P</strong>HP (версия 5.2 и выше)</li>
</ul>
<h2>Возможные проблемы</h2>
<p>
А теперь расскажем о проблемах с которыми Вам предстоит столкнуться
</p>
<h3>Конвертирование Видео</h3>
<p>
 Если позволить каждому из посетителей сайта заливать на сервер видеоролики в произвольном формате, то для того, чтобы просмотреть их все, Вам прийдется устанавливать на свой компьютер очень много кодеков, а если требовать определенный формат от пользователя &#8211; то, с очень большой вероятностью, это отпугнет от вашего сайта поситителей. И что же делать? Правильно, конвертировать все видеофайлы в один формат, и будем конфертировать в формат <a href="http://ru.wikipedia.org/wiki/FLV"  target="_blank" title="http://ru.wikipedia.org/wiki/FLV"  rel="nofollow">FLV</a> (flash video &#8211; можно просматривать в большинстве операционных систем, поскольку он использует широко распространённый Adobe Flash Player и плагины к большинству браузеров, а также поддерживается многими программами для воспроизведения видео, например, MPlayer, VLC media player и другими программами, работающими с помощью DirectShow).
</p>
<p>
Нам понадобятся следующие програмные средства (всё opensource):
</p>
<ol>
<li> <a href="http://ru.wikipedia.org/wiki/MEncoder" target="_blank" title="http://ru.wikipedia.org/wiki/MEncoder" rel="nofollow">mencoder</a> или <a href="http://ffmpeg.sourceforge.net" target="_blank" title="FFmpeg">FFmpeg</a>
</li>
<li> <a href="http://www.inlet-media.de/flvtool2" target="_blank" title="http://www.inlet-media.de/flvtool2" rel="nofollow">flvtool2</a> (требует наличия Ruby)
</li>
<li> <a href="http://anton.shevchuk.name/projects/program" target="_blank" title="Program package">PHP Program Package</a> (&#8216;example.php&#8217; пример конвертации с использованием mencoder&#8217;a) или <a href="http://www.phpclasses.org/browse/package/3747.html" target="_blank" title="ffmpeg class on phpclasses.org">ffmpeg class</a> (&#8216;ffmpeg.example1.php&#8217; пример конвертации с использованием ffmpeg)
</li>
</ol>
<p>
Дополнительно можно еще использовать <a href="http://ru.wikipedia.org/wiki/MPlayer" target="_blank" title="http://ru.wikipedia.org/wiki/MPlayer" rel="nofollow">mplayer</a>  для получения информации о оригинальном видеоролике.
</p>
<p>
Замечательно, если мы всё установили и правильно собрали, то мы теперь можем конвертировать&#8230;
</p>
<h3>Статус загрузки</h3>
<p>
 Еще такой момент &#8211; пользователям не нравиться сидеть и ждать пока файл загрузится на сервер, пользователь он же любознательный, ему хотя бы вывести progress bar надо:
</p>
<ul>
<li> <a href="http://www.emllabs.com/article.php?articleId=121"  target="_blank" title="http://www.emllabs.com/article.php?articleId=121"  rel="nofollow">http://www.emllabs.com/article.php?articleId=121/</a> (используя Flash8 и PHP)
</li>
<li> <a href="http://tomas.epineer.se/tesupload/"  target="_blank" title="http://tomas.epineer.se/tesupload/"  rel="nofollow">http://tomas.epineer.se/tesupload/</a>
</li>
<li> <a href="http://www.raditha.com/megaupload/"  target="_blank" title="http://www.raditha.com/megaupload/"  rel="nofollow">http://www.raditha.com/megaupload/</a>
</li>
<li> <a href="http://www.obokaman.com/p/descripcion-y-fuentes-del-upload-php-ajax-con-barra-de-progreso-1596"  target="_blank" title="http://www.obokaman.com/p/descripcion-y-fuentes-del-upload-php-ajax-con-barra-de-progreso-1596"  rel="nofollow">http://www.obokaman.com/p/descripcion-y-fuentes-del-upload-php-ajax-con-barra-de-progreso-1596</a>
</li>
<li> <a href="http://labs.beffa.org/w2box/demo/"  target="_blank" title="http://labs.beffa.org/w2box/demo/"  rel="nofollow">http://labs.beffa.org/w2box/demo/</a>
</li>
<li> <a href="http://trydobe.com/?page_id=3"  target="_blank" title="http://trydobe.com/?page_id=3"  rel="nofollow">http://trydobe.com/?page_id=3</a>
</li>
<li> <a href="http://ecosmear.com/relay/"  target="_blank" title="http://ecosmear.com/relay/"  rel="nofollow">http://ecosmear.com/relay/</a> (прикольный примерчик, используется perl)
</li>
</ul>
<p>
 Все ссылки нарыл на форуме xajax&rsquo;a <a href="http://community.xajaxproject.org/viewtopic.php?pid=10100"  target="_blank" title="http://community.xajaxproject.org/viewtopic.php?pid=10100"  rel="nofollow">http://community.xajaxproject.org/viewtopic.php?pid=10100</a>
</p>
<h3>Ресурсы</h3>
<p>
 Так, на сервер мы залили видеофайл, показали как он быстро к нам заливался, но вот беда, если мы будем на нашем web-сервере конвертировать видео ролики &#8211; то сайт у нас будет скорее мёртв, чем жив. Для этой цели нам надо будет использовать еще один (как минимум) сервер, который будет забирать неотконвертированный файлы с web-сервера и отправлять назад отконвертированные ролики. Т.е. для решение данной проблемы нам понадобиться еще железо&#8230;
</p>
<h3>Распределение нагрузки</h3>
<p>
 Конвертирование это ресурсоемко, а отдавать видеоролики всем желающим?&#8230; Это конечно не будет так нагружать процессор, но вот канал точно умрет&#8230; как выход у нас появляются еще сервера, которые и хранят у себя видеофайлы:
</p>
<ul>
<li> <a href="http://mirror1.myphptube.com" target="_blank" title="http://mirror1.myphptube.com" rel="nofollow">http://mirror1.myphptube.com</a>
</li>
<li> <a href="http://mirror2.myphptube.com" target="_blank" title="http://mirror2.myphptube.com" rel="nofollow">http://mirror2.myphptube.com</a>
</li>
<li> и т.д.
</li>
</ul>
<p>
Как распределять нагрузку &#8211; это уже решать Вам. Но прежде, чем городить огород Вы должны определить какой приблизительно объем данных Вам прийдеться хранить, и далее уже решать какая схема больше подойдет, ориентируемся, что 1 пользователь заливает на сервер 20mb в месяц (234Gb на 1000 пользователей в год), не популярные ролики не сохраняются более года):</p>
<ul>
<li><u>Объём данных ~ 0.3Tb &#8211; 1.5Tb</u>:<br />
 на каждом зеркале у нас хранятся все видеоролики<br />
 у нас есть mirror1 &#8211; сервер на котором всегда первым появляется переконвертированный видеоролик, остальные с ним синхронизируются
</li>
<li><u>Объём данных ~ 1.5Tb &#8211; 3 Tb</u>:<br />
 все видеоролики храняться только на одном главном сервере, если у видеоролика растет популярность, он заливается и на другие зеркала</li>
<li><u>Объём данных > 3Tb</u>:<br />
 видеролик заливается на ближайшее зеркало (подразумеваем, что ролик залитый китайцем будут смотреть в основном китайцы, следовательно заливаем его на зеркало в Китае)<br />
 по мере роста популярности ролика зеркалим его на сервер ближайший к эпицетру популярности (пример: китаец живет в США, его ролик залит на зеркало расположенное в США, смотрят его в основном в Китае, видя это ролик будет отзеркален на Китайский сервер)</li>
</ul>
<p>Числа взяты с потолка, против китайцев ничего не имею (просто взяты для примера), пишите свои варианты&#8230;
</p>
<h2>База данных</h2>
<p>
Далее я опишу простенькую архитектуру БД:
</p>
<table class="inline">
<tr>
<th colspan="2"> users </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>login</td>
<td> unique login </td>
</tr>
<tr>
<td>password</td>
<td> encrypt password </td>
</tr>
<tr>
<td>email</td>
<td> user email </td>
</tr>
<tr>
<td>actcode</td>
<td> activation code </td>
</tr>
<tr>
<td>role</td>
<td> ENUM(guest/user/admin) </td>
</tr>
<tr>
<td>status</td>
<td> not active / active / disable </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
<tr>
<td>date_update</td>
<td> date of last change profile </td>
</tr>
<tr>
<td>date_login</td>
<td> date of last login </td>
</tr>
<tr>
<td>&#8230;</td>
<td> another fields e.g. first name, last name </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> friends</th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>user_id1</td>
<td> user ID </td>
</tr>
<tr>
<td>user_id2</td>
<td> user ID </td>
</tr>
<tr>
<td>status</td>
<td> request / ok / cancel</td>
</tr>
<tr>
<td>date_create</td>
<td> date of send request </td>
</tr>
<tr>
<td>date_update</td>
<td> date of accept or denied request </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> files </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>title</td>
<td> title of video file </td>
</tr>
<tr>
<td>file</td>
<td> name of file on file system </td>
</tr>
<tr>
<td>status</td>
<td> not convert / in process / ok </td>
</tr>
<tr>
<td>access</td>
<td> public / members only / friends only / private </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>category_id</td>
<td> ID of category (categories)</td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
<tr>
<td>date_update</td>
<td> date of last changes </td>
</tr>
<tr>
<td>&#8230;</td>
<td> another fields e.g. length, description </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2">  mirrors </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field  </td>
</tr>
<tr>
<td>url</td>
<td> mirror url </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
<tr>
<td>date_update</td>
<td> date of last changes </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2">  mirrors_link </th>
</tr>
<tr>
<td>file_id</td>
<td> ID of file (files) </td>
</tr>
<tr>
<td>mirror_id</td>
<td> ID of mirror (mirrors) </td>
</tr>
<tr>
<td>status</td>
<td> current file status downloading / ok</td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
<tr>
<td>date_update</td>
<td> date of last changes </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> categories </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>pid</td>
<td> parent category ID</td>
</tr>
<tr>
<td>name</td>
<td> name of category </td>
</tr>
<tr>
<td>&#8230;</td>
<td> another fields e.g. metadescription, metakeywords </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> tags </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>word</td>
<td> tag word</td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> tags_link </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>tag_id</td>
<td> tag ID (tags) </td>
</tr>
<tr>
<td>file_id</td>
<td> file ID (files) </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> comments </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>file_id</td>
<td> file ID (files) </td>
</tr>
<tr>
<td>message</td>
<td> text of message </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> rate </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>file_id</td>
<td> file ID (files) </td>
</tr>
<tr>
<td>rate</td>
<td> integer value, e.g. for 0 to 10</td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> messages </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>user_id</td>
<td> ID of recipient (users) </td>
</tr>
<tr>
<td>type</td>
<td> e.g. friend request-response / admin message</td>
</tr>
<tr>
<td>author_folder</td>
<td> outbox/draft/delete </td>
</tr>
<tr>
<td>user_folder</td>
<td> inbox/delete </td>
</tr>
<tr>
<td>user_status</td>
<td> read or not </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> bookmarks </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>file_id</td>
<td> file ID (files) </td>
</tr>
<tr>
<td>title</td>
<td> title of link </td>
</tr>
<tr>
<td>description</td>
<td> some description </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
</table>
<p></p>
<p>
Небольшое примечание:
</p>
<ul>
<li> для полей ввида date_create и date_update используем функцию gmdate(&rsquo;Y-m-d H:i:s&rsquo;) &#8211; время по Гринвичу, это облегчит в дальнейшем жизнь при отображении времени на сайте.
</li>
</ul>
<h2>Команда</h2>
<p>
 Какую лучше всего собрать команду для разработки такого проекта? Я предлагаю следующий вариант:
</p>
<ul>
<li> 2 <acronym title="Hypertext Preprocessor">PHP</acronym>-разработчика
</li>
<li> Flash разработчик / дизайнер
</li>
<li> 1 администратор
</li>
<li> 1 тестировщик
</li>
<li> 1 менеджер
</li>
</ul>
<h2>Оценка</h2>
<table cellspacing="1" class="inline">
<tr>
<th colspan="3">Гость</th>
</tr>
<tr>
<td> Статические  странички</td>
<td> такие как &ldquo;Contact Us&rdquo;, &ldquo;Terms of Use&rdquo; etc. </td>
<td> 1h/page </td>
</tr>
<tr>
<td> Поиск  </td>
<td> простенький поиск по нескольким параметрам </td>
<td> 6h </td>
</tr>
<tr>
<td> Облако тэгов </td>
<td> </td>
<td> 8h </td>
</tr>
<tr>
<td> Просмотр видео </td>
<td> FLV video player </td>
<td> 16h </td>
</tr>
<tr>
<td> Просмотр комментариев </td>
<td> </td>
<td> 6h </td>
</tr>
<tr>
<td> Регистрация </td>
<td> включая валидацию e-mail </td>
<td> 12h </td>
</tr>
<tr>
<td> Напоминалка пароля </td>
<td> </td>
<td> 2h </td>
</tr>
<tr>
<th colspan="3">Пользователь</th>
</tr>
<tr>
<td> Login/Logout </td>
<td> </td>
<td> 2h </td>
</tr>
<tr>
<td> Upload file  </td>
<td> </td>
<td> 14h </td>
</tr>
<tr>
<td> Запись видео  </td>
<td> Необходим один из следующих серверов: <br/><br />
<a href="http://www.adobe.com/products/flashmediaserver/" title="Adobe Flash Media Server"   rel="nofollow">FMS</a>, <a href="http://www.wowzamedia.com/index.html" title="Wowza media system"  rel="nofollow">Wowza</a> (from Feb 2007) or <a href="http://osflash.org/red5" title="Red5 : Open Source Flash Server"  rel="nofollow">Red5</a> (opensource)
</td>
<td> 16h </td>
</tr>
<tr>
<td> Progress bar </td>
<td> </td>
<td> 16h </td>
</tr>
<tr>
<td> Добавление комментария </td>
<td> </td>
<td> 4h </td>
</tr>
<tr>
<td> Система рейтингов </td>
<td> </td>
<td> 2h </td>
</tr>
<tr>
<td> Закладки</td>
<td> create/edit/delete </td>
<td> 8h </td>
</tr>
<tr>
<th colspan="3">Администратор</th>
</tr>
<tr>
<td> Управление пользователями</td>
<td> Список пользователей, просмотр и редактирование профайлов</td>
<td> 16h </td>
</tr>
<tr>
<td> Управление категориями </td>
<td> </td>
<td> 16h </td>
</tr>
<tr>
<th colspan="3">Остальное</th>
</tr>
<tr>
<td> Дизайн </td>
<td> </td>
<td> 32h </td>
</tr>
<tr>
<td> Разработка БД </td>
<td> </td>
<td> 16h </td>
</tr>
<tr>
<td> Разработка архитектуры </td>
<td> </td>
<td> 32h </td>
</tr>
<tr>
<td> Хранилище файлов</td>
<td> от 8h до 96h </td>
<td> 8h </td>
</tr>
<tr>
<td>  Конвертирование видеофайлов </td>
<td> </td>
<td> 20h </td>
</tr>
<tr>
<th colspan="3">Итого</th>
</tr>
<tr>
<td>Настройка серверов</td>
<td> web-server, convert-server, mirrors </td>
<td> 40h </td>
</tr>
<tr>
<td>Разработка </td>
<td> </td>
<td> 256h </td>
</tr>
<tr>
<td>Тестирование</td>
<td> 30%-50% от разработки </td>
<td> 85h </td>
</tr>
<tr>
<td>Менеджмент </td>
<td> 10% минимум </td>
<td> 40h </td>
</tr>
<tr>
<th colspan="3" class="alignright">  <strong>Итого</strong>: 421h </th>
</tr>
</table>
<p></p>
<p>
 Да уж, не мало &#8211; 421 часа, т.е. примерно 2,5 месяца разработки&#8230; и это еще очень оптимистическая оценка, с учётом, что разработчики используют свои наработки или какую-либо CMF систему аналогичную <a href="http://framework.zend.com/" title="Zend Framework">Zend Framework</a> или <a href="http://anton.shevchuk.name/projects/phpxcore" title="phpXCore CMF">phpXCore</a>, а так же организовываем простейшее хранилище файлов. Если же разработка будет вестись с нуля &#8211; то можно смело умножать данную оценку на 2.<br />
<br/><br />
Итого, такой проект будет стоить не менее $10 000&#8230;
</p>
<h2>P.S.</h2>
<p>
 Основная проблема не в реализации системы, а в привличениии аудитории, кто будет пользоваться вашим сервисом если есть YouTube (и даже PornoTube)? Чем завлечь?  Если есть идеи &#8211; пишите каменты&#8230;
</p>
<p>
На момент написания статьи домен MyPHPTube.com не был зарегистрирован, если вы его таки зарегистрировали, вышлете пива на мой домашний адрес&#8230; ;)
</p>
<p>
Есть несколько причин побудивших написать данную статью:
</p>
<ol>
<li>хотелось написать умную статью для своего блога (или претендующую на &#8220;умную&#8221;)</li>
<li>хотелось показать, что <a href="http://anton.shevchuk.name/projects/program">Package Program</a> таки может пригодиться</li>
<li>продемонстрировать, что OpenSource и LAMP тоже рулит ;)</li>
</ol>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li><a href="http://anton.shevchuk.name/javascript/update-charts-hohli-com/" title="Обновление сервиса Charts.HoHli.com">Обновление сервиса Charts.HoHli.com</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-mouse-gestures/" title="JavaScript: программируем жесты мышкой">JavaScript: программируем жесты мышкой</a></li><li><a href="http://anton.shevchuk.name/php/php-cookbook-myphptubecom-en/" title="PHP CookBook: MyPHPTube.com (YouTube clone)">PHP CookBook: MyPHPTube.com (YouTube clone)</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/php/php-cookbook-myphptubecom/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>PHP CookBook: MyPHPTube.com (YouTube clone)</title>
		<link>http://anton.shevchuk.name/php/php-cookbook-myphptubecom-en/</link>
		<comments>http://anton.shevchuk.name/php/php-cookbook-myphptubecom-en/#comments</comments>
		<pubDate>Mon, 02 Jul 2007 14:56:06 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[Estimation]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB 2.0]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/uncategorized/php-cookbook-myphptubecom/</guid>
		<description><![CDATA[With the increased popularity of the YouTube.com service many people wanted to organize a similar service, but don’t know how to do this. If you are one of them &#8211; this article is for you Features First of all describe the basic site’s functions (and also determine and the role of users) : Guest View [...]]]></description>
			<content:encoded><![CDATA[<p align='center'><img src='http://anton.shevchuk.name/wp-content/uploads/2007/07/myphptube.png' alt='MyPHPTube' /></p>
<p>
With the increased popularity of the <a href="http://youtube.com"  target="_blank" title="http://youtube.com"  rel="nofollow">YouTube.com</a> service many people wanted to organize a similar service, but don’t know how to do this. If you are one of them &#8211; this article is for you
</p>
<p><span id="more-41"></span></p>
<h2>Features</h2>
<p>
First of all describe the basic site’s functions (and also determine and the role of users) :
</p>
<ol>
<li> Guest
<ul>
<li> View video online
</li>
</ul>
</li>
<li> Member
<ul>
<li> Upload videos
</li>
</ul>
</li>
<li> Administrator
<ul>
<li> Manage users
</li>
<li> Manage files
</li>
</ul>
</li>
</ol>
<h2>WEB 2.0 Features</h2>
<p>
We need to extend base functions, because we need to get more traffic:
</p>
<ol>
<li> Guest
<ul>
<li> view comments on video
</li>
<li> search for files (using categories or tags)
</li>
</ul>
</li>
<li> Member
<ul>
<li> comment on videos
</li>
<li> record video from Web (using webcam)
</li>
<li> assign category to video
</li>
<li> assign tag to video
</li>
<li> rate video
</li>
<li> organize list of friends
</li>
<li> manage favorites
</li>
<li> send in-mails
</li>
</ul>
</li>
<li> Administrator
<ul>
<li> Manage comments
</li>
<li> Manage categories
</li>
</ul>
</li>
</ol>
<p>These are certainly not all the features of YouTube, but at least something to start with</p>
<h2>Server Configuration</h2>
<p>Our system will be based on <acronym title="Linux Apache MySQL PHP">LAMP</acronym>:
</p>
<ul>
<li><strong>L</strong>inux</li>
<li><strong>A</strong>pache (version 2.2 and higher)</li>
<li><strong>M</strong>ySQL (version 5.0 and higher)</li>
<li><strong>P</strong>HP (version 5.2 and higher)</li>
</ul>
<h2>Troubleshooting</h2>
<p>
And now describe the problems that you may encounter
</p>
<h3>Video Conversion</h3>
<p>
To gain user attention we need to allow them uploading videos in any format, but it’s more comfortable to users to get videos in one specific format (this will allow not to have a codecs-zoo on your machine and on the other hand if site requires some extra actions from user – it is very likely that user will forget your site – you know we are lazy. And what can be done with this? The answer is obvious &#8211; convert video files into a single format, and the format should be <a href="http://en.wikipedia.org/wiki/FLV"  target="_blank" title="http://en.wikipedia.org/wiki/FLV"  rel="nofollow">FLV</a>. Flash-video can be viewed on most operating systems because it uses the widespread Adobe Flash Player software preinstalled on most browsers, and this format is also supported by many programs for video playback, such as MS MPlayer and almost all other players.
</p>
<p>
We need the following software tools (all opensource):
</p>
<ol>
<li> <a href="http://ru.wikipedia.org/wiki/MEncoder" target="_blank" title="http://ru.wikipedia.org/wiki/MEncoder" rel="nofollow">mencoder</a> or <a href="http://ffmpeg.sourceforge.net" target="_blank" title="FFmpeg">FFmpeg</a>
</li>
<li> <a href="http://www.inlet-media.de/flvtool2" target="_blank" title="http://www.inlet-media.de/flvtool2" rel="nofollow">flvtool2</a> (need Ruby)
</li>
<li> <a href="http://anton.shevchuk.name/projects/program" target="_blank" title="Program package">PHP Program Package</a> (&#8216;example.php&#8217; contains example using mencoder) or <a href="http://www.phpclasses.org/browse/package/3747.html" target="_blank" title="ffmpeg class on phpclasses.org">ffmpeg class</a> (&#8216;ffmpeg.example1.php&#8217; uses ffmpeg)
</li>
</ol>
<p>
You can use <a href="http://ru.wikipedia.org/wiki/MPlayer" target="_blank" title="http://ru.wikipedia.org/wiki/MPlayer" rel="nofollow">mplayer</a> to get additional information about original video file.
</p>
<p>
If we properly assembled and installed, we can now convert&#8230;
</p>
<h3>Upload</h3>
<p>
 People did not like to sit and wait while the file is silently downloaded to a server, the users are curious, so we would have to show progress bar:
</p>
<ul>
<li> <a href="http://www.emllabs.com/article.php?articleId=121"  target="_blank" title="http://www.emllabs.com/article.php?articleId=121"  rel="nofollow">http://www.emllabs.com/article.php?articleId=121/</a> (use Flash8 and PHP)
</li>
<li> <a href="http://tomas.epineer.se/tesupload/"  target="_blank" title="http://tomas.epineer.se/tesupload/"  rel="nofollow">http://tomas.epineer.se/tesupload/</a>
</li>
<li> <a href="http://www.raditha.com/megaupload/"  target="_blank" title="http://www.raditha.com/megaupload/"  rel="nofollow">http://www.raditha.com/megaupload/</a>
</li>
<li> <a href="http://www.obokaman.com/p/descripcion-y-fuentes-del-upload-php-ajax-con-barra-de-progreso-1596"  target="_blank" title="http://www.obokaman.com/p/descripcion-y-fuentes-del-upload-php-ajax-con-barra-de-progreso-1596"  rel="nofollow">http://www.obokaman.com/p/descripcion-y-fuentes-del-upload-php-ajax-con-barra-de-progreso-1596</a>
</li>
<li> <a href="http://labs.beffa.org/w2box/demo/"  target="_blank" title="http://labs.beffa.org/w2box/demo/"  rel="nofollow">http://labs.beffa.org/w2box/demo/</a>
</li>
<li> <a href="http://trydobe.com/?page_id=3"  target="_blank" title="http://trydobe.com/?page_id=3"  rel="nofollow">http://trydobe.com/?page_id=3</a>
</li>
<li> <a href="http://ecosmear.com/relay/"  target="_blank" title="http://ecosmear.com/relay/"  rel="nofollow">http://ecosmear.com/relay/</a> (nice example, using perl)
</li>
</ul>
<p>
 All references are from xajax forum <a href="http://community.xajaxproject.org/viewtopic.php?pid=10100"  target="_blank" title="http://community.xajaxproject.org/viewtopic.php?pid=10100"  rel="nofollow">http://community.xajaxproject.org/viewtopic.php?pid=10100</a>
</p>
<h3>Resources</h3>
<p>
 ТIf we will use the same server for webste and video conversion then website will be more dead than alive. For this purpose we will have to use another (one at least) server that will take original files from the web and put it back converted in a while. In other words we need more than 1 server to create a working solution.
</p>
<h3>Load distribution</h3>
<p>
 If we store all data in one server, it will not carry the load. We must have several servers to store data :
</p>
<ul>
<li> <a href="http://mirror1.myphptube.com" target="_blank" title="http://mirror1.myphptube.com" rel="nofollow">http://mirror1.myphptube.com</a>
</li>
<li> <a href="http://mirror2.myphptube.com" target="_blank" title="http://mirror2.myphptube.com" rel="nofollow">http://mirror2.myphptube.com</a>
</li>
<li> etc
</li>
</ul>
<p>
You must decide themselves how to distribute the load. You have to estimate the amount of data to be stored and then choose appropriate scheme, (let’s assume that one user uploads to a server 20mb per month (234Gb for 1000 users per year), and not popular files are not stored more than a year):</p>
<ul>
<li><u>Stored data  ~ 0.3Tb &#8211; 1.5Tb</u>:we keep all the videos on each mirror. We have main mirror – server on which converted video always appears first and all other mirrors sync with it
</li>
<li><u>Stored data  ~ 1.5Tb &#8211; 3 Tb</u>:<br />
 All videos are stored in one central server, if the video is growing in popularity, it is poured into other mirrors
</li>
<li><u>Stored data  > 3Tb</u>:<br />
 Video is uploaded to the nearest mirror (example : assume that the video uploaded from China will be mostly popular in China, thus place it to the mirror in China) With the growing popularity of this video we will copy it to the server closest to the epicentre of popularity (example : Chinese living in the United States, the video file upload to a mirror located in the United States, watched videos in China, in this situation video file will be copied to the Chinese server)</li>
</ul>
<p>This is not statistical numbers, they are for illustrative purposes. China cited as an example (nothing personal). Write an opinion in the comments&#8230;
</p>
<h2>DataBase</h2>
<p>
Next, I will describe simple architecture DB:
</p>
<table class="inline">
<tr>
<th colspan="2"> users </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>login</td>
<td> unique login </td>
</tr>
<tr>
<td>password</td>
<td> encrypt password </td>
</tr>
<tr>
<td>email</td>
<td> user email </td>
</tr>
<tr>
<td>actcode</td>
<td> activation code </td>
</tr>
<tr>
<td>role</td>
<td> ENUM(guest/user/admin) </td>
</tr>
<tr>
<td>status</td>
<td> not active / active / disable </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
<tr>
<td>date_update</td>
<td> date of last change profile </td>
</tr>
<tr>
<td>date_login</td>
<td> date of last login </td>
</tr>
<tr>
<td>&#8230;</td>
<td> another fields e.g. first name, last name </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> friends</th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>user_id1</td>
<td> user ID </td>
</tr>
<tr>
<td>user_id2</td>
<td> user ID </td>
</tr>
<tr>
<td>status</td>
<td> request / ok / cancel</td>
</tr>
<tr>
<td>date_create</td>
<td> date of send request </td>
</tr>
<tr>
<td>date_update</td>
<td> date of accept or denied request </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> files </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>title</td>
<td> title of video file </td>
</tr>
<tr>
<td>file</td>
<td> name of file on file system </td>
</tr>
<tr>
<td>status</td>
<td> not convert / in process / ok </td>
</tr>
<tr>
<td>access</td>
<td> public / members only / friends only / private </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>category_id</td>
<td> ID of category (categories)</td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
<tr>
<td>date_update</td>
<td> date of last changes </td>
</tr>
<tr>
<td>&#8230;</td>
<td> another fields e.g. length, description </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2">  mirrors </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field  </td>
</tr>
<tr>
<td>url</td>
<td> mirror url </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
<tr>
<td>date_update</td>
<td> date of last changes </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2">  mirrors_link </th>
</tr>
<tr>
<td>file_id</td>
<td> ID of file (files) </td>
</tr>
<tr>
<td>mirror_id</td>
<td> ID of mirror (mirrors) </td>
</tr>
<tr>
<td>status</td>
<td> current file status downloading / ok</td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
<tr>
<td>date_update</td>
<td> date of last changes </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> categories </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>pid</td>
<td> parent category ID</td>
</tr>
<tr>
<td>name</td>
<td> name of category </td>
</tr>
<tr>
<td>&#8230;</td>
<td> another fields e.g. metadescription, metakeywords </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> tags </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>word</td>
<td> tag word</td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> tags_link </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>tag_id</td>
<td> tag ID (tags) </td>
</tr>
<tr>
<td>file_id</td>
<td> file ID (files) </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> comments </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>file_id</td>
<td> file ID (files) </td>
</tr>
<tr>
<td>message</td>
<td> text of message </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> rate </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>file_id</td>
<td> file ID (files) </td>
</tr>
<tr>
<td>rate</td>
<td> integer value, e.g. for 0 to 10</td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> messages </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>user_id</td>
<td> ID of recipient (users) </td>
</tr>
<tr>
<td>type</td>
<td> e.g. friend request-response / admin message</td>
</tr>
<tr>
<td>author_folder</td>
<td> outbox/draft/delete </td>
</tr>
<tr>
<td>user_folder</td>
<td> inbox/delete </td>
</tr>
<tr>
<td>user_status</td>
<td> read or not </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
</table>
<p></p>
<table class="inline">
<tr>
<th colspan="2"> bookmarks </th>
</tr>
<tr>
<td>id</td>
<td> autoincrement field </td>
</tr>
<tr>
<td>author_id</td>
<td> ID of owner (users) </td>
</tr>
<tr>
<td>file_id</td>
<td> file ID (files) </td>
</tr>
<tr>
<td>title</td>
<td> title of link </td>
</tr>
<tr>
<td>description</td>
<td> some description </td>
</tr>
<tr>
<td>date_create</td>
<td> </td>
</tr>
</table>
<p></p>
<p>
A small note:
</p>
<ul>
<li>For the columns date_create and date_update using a gmdate (’Y-m-d H:i:s’) &#8211; GMT, it will make the life easier in the future when displaying the time on the site
</li>
</ul>
<h2>Team</h2>
<p>
 How to gather a team to develop such a project best? I propose the following:
</p>
<ul>
<li> 2 <acronym title="Hypertext Preprocessor">PHP</acronym>-Developer
</li>
<li> Flash Developer / Designer
</li>
<li> 1 UNIX-administrator
</li>
<li> 1 Tester
</li>
<li> 1 Manager
</li>
</ul>
<h2>Estimation</h2>
<table cellspacing="1" class="inline">
<tr>
<th colspan="3">Guest</th>
</tr>
<tr>
<td> Static pages </td>
<td> pages e.g. &ldquo;Contact Us&rdquo;, &ldquo;Terms of Use&rdquo; etc. </td>
<td> 1h/page </td>
</tr>
<tr>
<td> Search file  </td>
<td> simple search by several params </td>
<td> 6h </td>
</tr>
<tr>
<td> Tags Cloud </td>
<td> </td>
<td> 8h </td>
</tr>
<tr>
<td> View video </td>
<td> FLV video player </td>
<td> 16h </td>
</tr>
<tr>
<td> View comments </td>
<td> </td>
<td> 6h </td>
</tr>
<tr>
<td> Registration </td>
<td> Registration and activation via e-mail </td>
<td> 12h </td>
</tr>
<tr>
<td> Forgot password </td>
<td> </td>
<td> 2h </td>
</tr>
<tr>
<th colspan="3">User</th>
</tr>
<tr>
<td> Login/Logout </td>
<td> </td>
<td> 2h </td>
</tr>
<tr>
<td> Upload file  </td>
<td> </td>
<td> 14h </td>
</tr>
<tr>
<td> Record video  </td>
<td> Requried  media server: <br/><br />
<a href="http://www.adobe.com/products/flashmediaserver/" title="Adobe Flash Media Server"   rel="nofollow">FMS</a>, <a href="http://www.wowzamedia.com/index.html" title="Wowza media system"  rel="nofollow">Wowza</a> (from Feb 2007) or <a href="http://osflash.org/red5" title="Red5 : Open Source Flash Server"  rel="nofollow">Red5</a> (opensource)
</td>
<td> 16h </td>
</tr>
<tr>
<td> Progress bar </td>
<td> </td>
<td> 16h </td>
</tr>
<tr>
<td> Send Comment </td>
<td> </td>
<td> 4h </td>
</tr>
<tr>
<td> Rate File    </td>
<td> </td>
<td> 2h </td>
</tr>
<tr>
<td> Bookmarks management </td>
<td> create/edit/delete </td>
<td> 8h </td>
</tr>
<tr>
<th colspan="3">Admin</th>
</tr>
<tr>
<td> Users management </td>
<td> The names and details  of members who have been registered are listed showing the date their account was created and other user info. <br/><br />
 Options are available for Administrator: view Member details,  ban Members, search for existing users by First or Last name or Username etc.</td>
<td> 16h </td>
</tr>
<tr>
<td> Categories management </td>
<td> </td>
<td> 16h </td>
</tr>
<tr>
<th colspan="3">Others</th>
</tr>
<tr>
<td> Design </td>
<td> </td>
<td> 32h </td>
</tr>
<tr>
<td> Database Design </td>
<td> </td>
<td> 16h </td>
</tr>
<tr>
<td> Project Architecture Design </td>
<td> </td>
<td> 32h </td>
</tr>
<tr>
<td> Organize File Storage </td>
<td> From 8h to 96h </td>
<td> 8h </td>
</tr>
<tr>
<td> Convert process </td>
<td> </td>
<td> 20h </td>
</tr>
<tr>
<th colspan="3">Total</th>
</tr>
<tr>
<td>Environment setup </td>
<td> configure web-server, convert-server, mirrors </td>
<td> 40h </td>
</tr>
<tr>
<td>Development </td>
<td> </td>
<td> 256h </td>
</tr>
<tr>
<td>Testing </td>
<td> 30%-50% of all development </td>
<td> 85h </td>
</tr>
<tr>
<td>Management </td>
<td> 10% of all time </td>
<td> 40h </td>
</tr>
<tr>
<th colspan="3" class="alignright">  <strong>Total</strong>: 421h </th>
</tr>
</table>
<p></p>
<p>
So we have 421 hours, or approximately 2.5 months of development. Did you expect such a number? I thought it will be more :)<br />
<br/><br />
That&#8217;s very optimistic estimation that includes several assumptions:</p>
<ul>
<li>the developers will use CMF system similar to <a href="http://anton.shevchuk.name/projects/phpxcore" title="phpXCore CMF">phpXCore</a> or <a href="http://framework.zend.com/" title="Zend Framework">Zend Framework</a></li>
<li>the developers are familiar with the CMF choosen (i.e. won’t learn in while coding)</li>
<li>the simplest file storage will be used (all mirrors store all files)</li>
</ul>
<p>If development will be done from scratch you can easily multiply this assessment by 2. <br/><br />
Total, the project will cost at least $ 10,000&#8230;
</p>
<h2>P.S.</h2>
<p>
The main problem is not in the system, main problem is drawing audience. Who will use your service if there is YouTube (and even PornoTube)? If you have ideas, write in comments&#8230;
</p>
<p>
At the time of writing this article MyPHPTube.com domain was not registered. If you register it, send a beer at my home address&#8230; ;)</p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li><a href="http://anton.shevchuk.name/javascript/update-charts-hohli-com/" title="Обновление сервиса Charts.HoHli.com">Обновление сервиса Charts.HoHli.com</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-mouse-gestures/" title="JavaScript: программируем жесты мышкой">JavaScript: программируем жесты мышкой</a></li><li><a href="http://anton.shevchuk.name/php/php-cookbook-myphptubecom/" title="PHP CookBook: MyPHPTube.com (клонируем YouTube)">PHP CookBook: MyPHPTube.com (клонируем YouTube)</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/php/php-cookbook-myphptubecom-en/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>

