Проброс USB устройств в VirtualBox

И так выведем для начало весь список USB устройств, делаем под sudo

sudo VBoxManage list usbhost

нас интересует:

UUID: 59b370b3-c176-42d5-814b-b805295c9738
VendorId: 0×0529 (0529)
ProductId: 0×0001 (0001)
Revision: 2.23 (0223)
Manufacturer: AKS
Product: HASP 2.17
Address: sysfs:/sys/devices/pci0000:00/0000:00:1d.2/usb4/4-2//device:/dev/vboxusb/004/002
Current State: Available

Теперь это же проверим из под нашего vbox юзера

VBoxManage list usbhost

если все так же то пропускаем, если вывод пустой, то тогда нашего пользователя, от которого запускаем ВМ надо добавить в группу vboxusers
Создать в файл с правилами для udev /etc/udev/rules.d/10-vboxdrv.rules
со следующим содержанием:


SUBSYSTEM==usb, ENV{DEVTYPE}==usb_device, GROUP=vboxusers, MODE:=0664

И проверить права на /sys/bus/usb/devices

ls -lh /sys/bus/usb/devices

Должны быть права root:vboxusers

И так добавляем фильтр

VBoxManage  usbfilter add 0 --target WS1 --name HASP1C --action hold --active yes --vendorid 0529 --productid 0001 --revision 0223  --manufacturer AKS

0 – номер правила
—target WS1 –наша виртуальная машина WS1
—name HASP1C – Имя фильтра
—action hold – значит блокируем доступ
—vendorid 0529 – берем из вывода VBoxManage list usbhost
Остальные параметры оттуда же

Теперь настроим саму виртуальную машину, включим поддержку usb

VBoxManage modifyvm WS1 --usb on

А теперь проверим наш фильтр

VBoxManage showvminfo WS1

Видим следующий текст


USB: enabled

USB Device Filters:

Index: 0
Active: yes
Name: HASP1C
VendorId: 0529
ProductId: 0001
Revision: 0223
Manufacturer: AKS

Значит все работает, теперь можно загружать вашу виртуальную машину и ставить драйвера на USB устройство.

Codeigniter. Модель для рейтинга, часть 2

И так в прошлой статье мы создали модель для нашего рейтинга, но стандартный способ вызова модели в codeigniter не очень нам подходит, так как не позволяет работать с моделью, как с объектом создавая множество объектов данного типа.

Что бы было понятней, в дальнейшем понадобится возвращать внутри объекта каталог, объект оценку и вот тут стандартный способ работы с моделью станет не возможен.

При стандартной работе с моделью


$this->load->model(‘rating’);

Создается один объект и последующие вызовы возвращают указатель на этот объект.
В новой версии можно делать так:


$rating = new Rating();
$rating2 = new Rating();

И так изменённая модель Rating


Class Rating { /** * Ид оценки * @var int */ public $rating_id = NULL; /** * Общая оценка * @var float */ public $rate = NULL; /** * Кол-во проголосовавших * @var int */ public $voted = NULL; /** * Активна оценка или нет * @var bool */ public $active = NULL; /** * Имя нашей таблицы в бд * @var string */ private $_table_name; /** * Максимально возможная оценка * @var int */ private $_max_rate = 5; private $_CI; public function __construct() { $this->_CI = & get_instance(); $this->_CI->config->load(‘rating’); if (($this->_table_name = $this->_CI->config->item(‘table_name’, ‘rating_config’)) === FALSE) { //Если не получил имя таблицы, то выводим окно ошибки show_error(‘Не удалось получить имя таблицы в базе данных для системы оценок’); } $this->_max_rate = $this->_CI->config->item(‘max_rate’, ‘rating_config’); } /** * Создаем оценку * param float $rate - Оценка, по умолчанию 0 * param int $voted – Кол-во проголосовавших * param bool $active - Активировать оценку * return bool – результат создания объекта */ public function create($rate = 0, $voted = 0, $active = true) { $sql = “INSERT INTO “ . $this->_table_name . “ (rate,voted,active) VALUES;”; $this->_CI->db->query($sql, array($rate, $voted, $active)); if ($this->_CI->db->affected_rows() > 0) { $this->rating_id = $this->_CI->db->insert_id(); $this->rate = $rate; $this->voted = $voted; $this->active = $active; return TRUE; } else { $this->_clear_rate(); return FALSE; } } /** * Удаляем оценку * param type $id - ид оценки, если не указан ид, то пытается удалить текущий объект * return boolean – результат удаления */ public function delete($id = false) { if ($id !== false) { $this->_CI->db->delete($this->_table_name, array(‘rating_id’ => $id)); } else { if (is_numeric($this->rating_id)) { $this->_CI->db->delete($this->_table_name, array(‘rating_id’ => $this->rating_id)); } else { return FALSE; } } if ($this->_CI->db->affected_rows() > 0) { if (($id = false) || ($id $this->rating_id)) { $this->_clear_rate(); } return TRUE; } else { return FALSE; } } /** * Клас ищет оценку по ид * param type $id - ид оценки * param type $active – искать только активные * @return boolean – true если нашел, ну или false */ public function find_by_id($id, $active = true) { $sql = “SELECT rating_id,rate,voted,active FROM “ . $this->_table_name . “ WHERE rating_id=?”; $result = null; if ($active) { $sql .= “ AND active=?”; $result = $this->_CI->db->query($sql, array($id, $active)); } else { $result = $this->_CI->db->query($sql, array($id)); } if ($result->num_rows() > 0) { $tmp = $result->row(); $this->rating_id = $tmp->rating_id; $this->rate = $tmp->rate; $this->voted = $tmp->voted; $this->active = $tmp->active; return TRUE; } else { $this->_clear_rate(); return FALSE; } } /** * Редактируем данные * @return boolean результат обновления */ public function edit() { if (is_numeric($this->rating_id)) { $sql = “UPDATE “ . $this->_table_name . “ SET rate=?,voted=?,active=? WHERE rating_id=?”; $this->_CI->db->query($sql, array($this->rate, $this->voted, $this->active, $this->rating_id)); if ($this->_CI->db->affected_rows() > 0) { return TRUE; } else { return FALSE; } } else { return FALSE; } } /** * Добаляем оценку * param type $rate - оценка проголосовавшего * param type $id – ид оценки, если не указывать, то попытается использховать текущий объект * param type $ret - возращать обновленный объект или нет * return boolean если $ret=true, то вернет объект с новыми данными, если $ret=false, то просто вернет true */ public function add_rate($rate, $id = FALSE, $ret = TRUE) { $sql = “UPDATE “ . $this->_table_name . “ SET voted = voted+1, rate = ROUND)+?)/voted,1) WHERE rating_id=?”; if ($rate > $this->_max_rate) $rate = $this->_max_rate; if ($id !== FALSE) { $this->_CI->db->query($sql, array($rate, $id)); } else { if (is_numeric($this->rating_id)) { $this->_CI->db->query($sql, array($rate, $this->rating_id)); $id = $this->rating_id; } else { return FALSE; } } if ($this->_CI->db->affected_rows() > 0) { if ($ret) { return $this->find_by_id($id); } return TRUE; } else { return FALSE; } } /** * Возвращает максимальную оценку * @return int */ public function get_max_rate() { return $this->_max_rate; } /** * Удаляем значения */ private function _clear_rate() { $this->rating_id = NULL; $this->rate = NULL; $this->voted = NULL; $this->active = NULL; } } ?>

Теперь в папке application/controllers создадим два контроллера
ajax.php – для обработка ajax запросов
rate.php – для тестирования работы

код ajax.php


BASEPATH’)) exit(‘No direct script access allowed’); class Ajax extends CI_Controller { public function __construct() { parent::__construct(); } /** * Возращает результат добаления оценки * param type $id - id оценки * param type $rate – rate оценка */ public function rate($id = false, $rate = false) { if ($id !== false) { require_once APPPATH . ‘models/Rating.php’; $this->load->helper(‘rating’); $rating = new Rating(); $id = preg_replace(’/[^0-9]/’, ‘’, $id); if ($rate !== false) { $rate = preg_replace(’/[^0-9]/’, ‘’, $rate); $rating->add_rate($rate, $id); set_rating_cookie(1); $data[‘rating’] = $rating; $this->load->view(‘rate/result’, $data); } } } } ?>

код rate.php


BASEPATH’)) exit(‘No direct script access allowed’); class Rate extends CI_Controller { private $rating; public function __construct() { parent::__construct(); require_once APPPATH . ‘models/Rating.php’; } /** * * @param type $id – ид оценки */ public function view($id = false) { if($id!== false) { $id = preg_replace(’/[^0-9]/’, ‘’, $id);//оставляем только цифры $this->rating = new Rating(); if ($this->rating->find_by_id($id)) { $this->load->view(‘head’); $data[‘rating’] = $this->rating; $this->load->helper(‘rating’); $this->load->view(‘rate/result’, $data); if(!exist_rating_cookie($this->rating->rating_id)) { $this->load->view(‘rate/voted’, $data); } $this->load->view(‘foot’); } } else { $this->load->view(‘head’); echo ‘

No id rate

’; $this->load->view(‘foot’); } }
}
?>

Теперь создадим хелпер для работы с куками в папке application/helpers создаем rating_helper.php


BASEPATH’)) exit(‘No direct script access allowed’); /** * Проверяет и устанавливает куки * param type $rating_id - ид оценки * return boolean – результат добавления */
function set_rating_cookie($rating_id) { $CI = & get_instance(); $rating = $CI->input->cookie(‘rating’, TRUE); if ($rating !== false) { $rating = unserialize($rating); if (is_array($rating)) { if (array_search($rating_id, $rating) === false) { $rating[] = $rating_id; } else { return FALSE; } } else { $rating = array($rating_id); } } else { $rating = array($rating_id); } $cookie = array( ‘name’ => ‘rating’, ‘value’ => serialize($rating), ‘expire’ => ‘86500’, //24 часа ‘secure’ => false ); $CI->input->set_cookie($cookie); return TRUE; } /** * Функция проверяет существует ли заданая кука для оценки * param type $rating_id - ид оценки * return boolean – результат существования */
function exist_rating_cookie($rating_id) { $CI = & get_instance(); $rating = $CI->input->cookie(‘rating’, TRUE); if ($rating !== false) { $rating = unserialize($rating); if (is_array($rating)) { if (array_search($rating_id, $rating) !== false) { return TRUE; } else { return FALSE; } } else { return FALSE; } } else { return FALSE; }
} ?>

В контроллере rate у нас идет вызов 4 представлений
1. head – шапка сайта
2. rate/result – форма вывода результатов голосования
3. rate/voted – форма для голосования
4. foot – подвал сайт

Теперь создадим их в папке application/view создаем файл head.php












Там же foot.php

%MINIFYHTML87ab3311834efe6bc1c8a6edc974809d2%

Теперь создадим папку rate и в ней 2 файла result.php и voted.php

result.php





Оценка: rate; ?>



Всего проголосовало: voted; ?>


voted.php





Оцените:
$max = $rating->get_max_rate();
for ($i = 1; $i <= $max; $i++) {
echo ‘rating_id . ‘,’ . $i . ‘);>’ . $i . ‘ ‘;
}
?>


Теперь если мы создадим тестовый рейтинг выполнив запрос к базе:
INSERT INTO rating (rate,voted,active) VALUES(0,0,TRUE);

И обратимся к нашему сайту http://ip-addres/путь-к-codeigniter/rate/view/1

Страница

Увидим следующую страницу, теперь проголосовав, нажав на одну из оценок, наша система обновит страницу по средствам ajax запроса

Результат

После чего в куках появится id оценки и на 24 часа вы не сможете больше голосовать.

Установка phpvirtualbox web интерфейс для virtualbox

Последнию версию можно взять с сайта http://phpvirtualbox.googlecode.com, там же есть документация по установке на различные системы. И так скачиваем и распаковываем:


wget  http://phpvirtualbox.googlecode.com/files/phpvirtualbox-4.1-10.zip
unzip phpvirtualbox-4.1-10.zip

Ставим apache с php


sudo apt-get install apache2
sudo apt-get install libapache2-mod-php5

В конфигах apache смотрим опцию DocumentRoot у меня это /var/www
Теперь копирую туда файлы phpvirtualbox


cp -R phpvirtualbox-4.1-10 /var/www/vbox
cd /var/www/vbox

создаем файл настроек


cp config.php-example config.php

И редактируем его


//тут указываем вашего системного юзера под которым работает virtualbox
var $username = ‘vbox’;
var $password = ‘pass’;
var $language = ‘ru’;

Добавляем в /etc/default/virtualbox


VBOXWEB_USER=vbox
VBOXWEB_HOST=127.0.0.1

Теперь небольшой момент, те кто как я пользуются OSE версией, то обнаружат, что у нас отсутствует файл /etc/init.d/vboxweb-service и что бы нам запустить vboxwebsrv пишем:


 vboxwebsrv -b -F /dev/null

Тут указываем, что бы он запустился в бэкграунде, а логи выводил в /dev/null. Для дальнейшего использования, нужно будет создать скрипт автозапуска и остановки vboxwebsrv.

Обладателям oracle версии virtualbox нужно просто запустить скрипт


/etc/init.d/vboxweb-service  start

Проверяем как запустился наш vboxwebserver


ps aux | grep vboxwebsrv

и видим, что нормально 16482 0.0 0.4 40208 7232 ? Sl 12:25 0:00 /usr/lib/virtualbox/vboxwebsrv -b -F /dev/null

теперь заходим http://ваш-ip-address-server-vm/vbox/ и вводим admin admin

Заходим

Если все работает правильно, то увидите такое окно

Интерфейс

Дальше как в обычно gui интерфейсе virtualbox’a

VirtualBox задать частоту процессора для Виртуальной машины

Задать тактовую частоту на прямую для ВМ в virtualbox нельзя, но есть параметр cpuexecutioncap, который задает ограничение на использование времени ЦП, что это даст, если скажем у нас процессор 3000 Mhz , а мы хотим сделать 4 виртуальные машины:

2 частотой примерно 1 Ghz

1 частотой 400 Mhz

1 частотой 600 Mhz

То для этого нужно будет указать для уже созданных виртуальных машин:

VBoxManage modifyvm VM1 —cpuexecutioncap 33
33% от общего времени цп гипервизора для виртуальной машины VM1

VBoxManage modifyvm VM2 —cpuexecutioncap 33

VBoxManage modifyvm VM3 —cpuexecutioncap 14

VBoxManage modifyvm VM4 —cpuexecutioncap 20

На самом деле это нам не даст реальных частот, которые нам нужны и процессор ВМ все равно будет равен частоте реального процессора, но загрузка данного процесса будет не выше 33% для VM1, что в принципе будет равно той частоте в 1Ghz, которую мы хотим получить(хотя конечно сравнение не корректно).

Что бы проверить все это можно скачать и поставить на нашу VM unixbench
И так для начала ставим тест, можно скачать последнею версию отсюда:
http://code.google.com/p/byte-unixbench/

ставим:


wget http://members.dslextreme.com/users/andylee/unixbench-4.1.0-wht.tar.gz
gunzip -dvc unixbench-4.1.0-wht.tar.gz | tar xvf -
cd unixbench-4.1.0-wht
make
./Run

И так первый тест на 100%

Dhrystone 2 using register variables 104.8
Double-Precision Whetstone 79.0
Execl Throughput 4.5
File Copy 1024 bufsize 2000 maxblocks 203.1
File Copy 256 bufsize 500 maxblocks 158.5
File Read 4096 bufsize 8000 maxblocks 202.1
Pipe-based Context Switching 1.9
Pipe Throughput 28.6
Process Creation 3.5
Shell Scripts (8 concurrent) 6.2
System Call Overhead 43.1
FINAL

SCORE 29.1

Теперь та же ВМ, но уже с ограничением в 50%

Dhrystone 2 using register variables 47.8
Double-Precision Whetstone 40.7
Execl Throughput 2.2
File Copy 1024 bufsize 2000 maxblocks * 98.7*
File Copy 256 bufsize 500 maxblocks 75.8
File Read 4096 bufsize 8000 maxblocks 102.4
Pipe-based Context Switching * 1.1*
Pipe Throughput 13.7
Process Creation 1.7
Shell Scripts (8 concurrent) 3.1
System Call Overhead 20.1
FINAL SCORE 14.3

А вот например та же ВМ, но уже ограничение 45%

Dhrystone 2 using register variables 36.6
Double-Precision Whetstone 31.7
Execl Throughput * 1.6*
File Copy 1024 bufsize 2000 maxblocks * 79.5*
File Copy 256 bufsize 500 maxblocks 60.8
File Read 4096 bufsize 8000 maxblocks * 82.7*
Pipe-based Context Switching 0.8
Pipe Throughput * 12.0*
Process Creation 1.3
Shell Scripts (8 concurrent) 2.2
System Call Overhead * 13.1*
FINAL SCORE 11.0

А это уже скрин top’a с гипервизора, тут запущено 2 машины 1 с ограничением в 45% , на ней в данный момент работает наш тест и ее загрузка 43,7%
Ограничение

А тут уже ограничение в 80% на эту ВМ
Ограничение

Как видите из тестов можно например предоставить 1 сервер нескольким компаниям и использовать для виртуализации VirtualBox. Так же интересно различие на операциях с плавающий точкой на железе оно у меня составило
Double-Precision Whetstone 82.5
А на виртуалке
Double-Precision Whetstone 79.0
Т.е. потери при полной виртуализации потери были около 4% от железа.

Ставим Windows 2008 в VirtualBox из консоли

Для начало найдем нужный нам ostype


VBoxManage list ostypes | grep Windows

В списке ищем 2008 винду
ID: Windows2008
Description: Windows 2008

Нашли, теперь создадим нашу ВМ


VBoxManage createvm --name WS1 --ostype Windows2008 --register --basefolder /disk

Получаем ответ, что все ок
Virtual machine ‘WS1’ is created and registered.
UUID: 9bf1df5a-3334-4de2-8571-1e99ffe851c6
Settings file: ‘/disk/WS1/WS1.vbox’

Создаем интерфейс, как сделать смотрите тут

Устанавливаем параметры нашего будущего сервера:


VBoxManage modifyvm WS1 --memory 1024 --floppy disabled --audio none --nic1 bridged --bridgeadapter1 virt2 --vram 16 --accelerate3d off --boot1 disk --acpi on --cableconnected1 on

Создаем диск ~14гб, можно и больше


VBoxManage createhd --filename /disk/WS1.img --size 15000

создаем виртуальный ide


VBoxManage storagectl WS1 --name WSHDD --add ide

И добавляем к нему, наш созданый до этого диск


VBoxManage storageattach WS1 --storagectl WSHDD --port 0 --device 0 --type hdd --medium /disk/WS1.img

Теперь добавим dvd к нашей ВМ , для этого устанавливаем диск с Windows 2008 Server в привод и указваем его


VBoxManage storageattach WS1 --storagectl WSHDD --port 1 --device 0 --type dvddrive --medium host:/dev/cdrom1

Указываем ВМ, что загружаться с нужно с dvd


VBoxManage modifyvm WS1 --boot1 dvd

И запускаем нашу VM с возможностью подключения по vnc


VBoxHeadless -s WS1 -n -m 5900 -o 1234

Теперь просто подключаемся к серверу, где установлен virtualbox c помощью vnc клиента с паролем 1234

И смотрим за процессом установки
Подключаемся

Указываем

Выбираем

Ждем

Рабочий

Вот и все собственно.

Подключаем к ip телефонам cisco доп панель spa500s

И так кто не читал, как настроить tftpd смотрит статью по настройке cisco фонов и tftpd читают ее.

Что нам надо, основное уже создано, теперь в конфиг телефонов добавляем строчку:


Asterisk

Тут мы указываем, что наш sip сервер Asterisk.

А затем просто добавляем номера на каждую кнопку:


fnc=blf+sd;sub=1234@192.168.1.1
fnc=blf+sd;sub=1235@192.168.1.1

Тут:
Unit_1 – номер доп модуля, если у вас их 2, то будет соответсвенно еще Unit_2
Key_1 – номер клавиши
1235@192.168.1.1 – телефон который добавляем и сервер
blf – индекатор занятой линии(будет гореть красным лампа)
sd – быстрый набор

Теперь можно перезагрузить телефон и он автоматически загрузит настройки. Тем кому надо более подробно, прошу качать оффициальный мануал по настройке:
SPA500S_Asterisk_03152010.pdf

Настраиваем git сервер для удаленного использования с клиентом(windows|Linux)

установим сначало git


apt-get install git

Заходим на наш сервер и создаем пользователя


useradd -b /disk -s /bin/bash git -m

тут
-b /disk – домашняя директория
-s /bin/bash – шелл по умолчанию
-m – создать в домашней директории(/disk) папку пользователя git

Теперь нам надо создать пустой репозиторий
для этого идем заходим под вновь созданным пользователем в домашнею папку


su git
cd

создаем каталог с именем нашего проекта


mkdir project_name
cd project_name

инициализируем репозиторий


git --bare init

—bare – указывает, что создать надо пустой репозиторий

Все на этом настройка сервера закончена. Теперь нужно настроить клиент. Для этого качаем windows версию git клиента
Для этого заходим

http://git-scm.com/downloads

И качаем клиент, затем устанавливаем его, запускаем git bash

В самом gitbash переходим в папку с вашим проектом


cd /D/myprohect

И инициализируем удаленный репозиторий


git init
git add .
git commit -m ‘запуск
git remote add origin ssh://git@gitserver:port/disk/git/project
git push origin master

Теперь можно добавлять изменения в репозиторий используя команду:


git commit -am ‘Еще один коммит’
git push origin master

Так же для получения репозитория на другом компьютере достаточно выполнить


git clone ssh://git@gitserver:port/disk/git/project

Для безопасности замените shell в /etc/passwd у нашего пользователя с /bin/bash на /usr/bin/git-shell

Codeigniter. Создаем модель для рейтинга.

И так поехали объяснять как поставить codeigniter,apache и прочее я не буду и изначально расчитываю на набор необходимых знаний , создадим таблицу под нашу будущею систему оценок.
Создаем таблицу, я пишу под mysql, но если у вас есть понимание можно и под psql все сделать и так создаем:


CREATE TABLE `rating`( `rating_id` INT(5) NOT NULL AUTO_INCREMENT, `rate` FLOAT(1), `voted` INT(7), `active` BOOL, PRIMARY KEY (`rating_id`) ); 

rating_id – наш ключ, по которому мы будем находить оценку и работать с ней
rate – сама оценка
voted – кол-во проголосовавших
active – возможность отключить голосовалку без удаления и вернуть обратно

Как же эта система будет взаитмодействовать с другими элементами сайта, да легко. Мы просто
сможем добавить в любую таблицу например article поле rating_id, или в таблицу images то же поле
и привязать к объекту нашу оценку.

Для начало создадим конфигурационный файл в папке applicationconfig создаем rating.php
И добавляем в него наши настройки


$rating_config[‘table_name’] = ‘rating’; // Максимально допустимая оценка
$rating_config[‘max_rate’] = 10; //Добавляем к основному конфигу
$config[‘rating_config’] = $rating_config;
?>

Приступим к реализации, создадим в папке applicationmodels файл Rating.php
со следующим значением:


config->load('rating');
        if (($this->_table_name = $this->config->item('table_name', 'rating_config')) === FALSE) {
            //Если не получил имя таблицы, то выводим окно ошибки
            show_error('Не удалось получить имя таблицы в базе данных для системы оценок');
        }
        $this->_max_rate = $this->config->item('max_rate', 'rating_config');
    }

    /**
     * Создаем оценку
     * @param float $rate - Оценка, по умолчанию 0
     * @param int $voted - Кол-во проголосовавших
     * @param bool $active - Активировать оценку
     * @return bool - результат создания объекта
     */
    public function create($rate = 0, $voted = 0, $active = true) {
        $sql = INSERT INTO  . $this->_table_name .  (rate,voted,active) VALUES(?,?,?);;
        $this->db->query($sql, array($rate, $voted, $active));
        if ($this->db->affected_rows() > 0) {
            $this->rating_id = $this->db->insert_id();
            $this->rate = $rate;
            $this->voted = $voted;
            $this->active = $active;
            return TRUE;
        } else {
            $this->_clear_rate();
            return FALSE;
        }
    }

    /**
     * Удаляем оценку
     * @param type $id - ид оценки, если не указан ид, то пытается удалить текущий объект
     * @return boolean - результат удаления
     */
    public function delete($id = false) {
        if ($id !== false) {
            $this->db->delete($this->_table_name, array('rating_id' => $id));
        } else {
            if (is_numeric($this->rating_id)) {
                $this->db->delete($this->_table_name, array('rating_id' => $this->rating_id));
            } else {
                return FALSE;
            }
        }
        if ($this->db->affected_rows() > 0) {
            if (($id === false) || ($id == $this->rating_id)) {
                $this->_clear_rate();
            }
            return TRUE;
        } else {
            return FALSE;
        }
    }

    /**
     * Клас ищет оценку по ид
     * @param type $id - ид оценки
     * @param type $active - искать только активные
     * @return boolean - true если нашел, ну или false
     */
    public function find_by_id($id, $active = true) {
        $sql = SELECT rating_id,rate,voted,active FROM  . $this->_table_name .  WHERE rating_id=?;
        $result = null;
        if ($active) {
            $sql .=  AND active=?;
            $result = $this->db->query($sql, array($id, $active));
        } else {
            $result = $this->db->query($sql, array($id));
        }
        if ($result->num_rows() > 0) {
            $tmp = $result->row();
            $this->rating_id = $tmp->rating_id;
            $this->rate = $tmp->rate;
            $this->voted = $tmp->voted;
            $this->active = $tmp->active;
            return TRUE;
        } else {
            $this->_clear_rate();
            return FALSE;
        }
    }

    /**
     * Редактируем данные
     * @return boolean результат обновления
     */
    public function edit() {
        if (is_numeric($this->rating_id)) {
            $sql = UPDATE  . $this->_table_name .  SET rate=?,voted=?,active=? WHERE rating_id=?;
            $this->db->query($sql, array($this->rate, $this->voted, $this->active, $this->rating_id));
            if ($this->db->affected_rows() > 0) {
                return TRUE;
            } else {
                return FALSE;
            }
        } else {
            return FALSE;
        }
    }

    /**
     * Добаляем оценку
     * @param type $rate - оценка проголосовавшего
     * @param type $id - ид оценки, если не указывать, то попытается использховать текущий объект
     * @param type $ret - возращать обновленный объект или нет
     * @return boolean если $ret=true, то вернет объект с новыми данными, если $ret=false, то просто вернет true
     */
    public function add_rate($rate, $id = FALSE, $ret = TRUE) {
        $sql = UPDATE  . $this->_table_name .  SET voted = voted+1, rate = ROUND(((rate*(voted-1))+?)/voted,1)  WHERE rating_id=?;
        if ($rate > $this->_max_rate)
            $rate = $this->_max_rate;
        
        if ($id !== FALSE) {
            $this->db->query($sql, array($rate, $id));
        } else {
            if (is_numeric($this->rating_id)) {
                $this->db->query($sql, array($rate, $this->rating_id));
                $id = $this->rating_id;
            } else {
                return FALSE;
            }
        }

        if ($this->db->affected_rows() > 0) {
            if($ret) {
                return $this->find_by_id($id);
            }
            return TRUE;
        } else {
            return FALSE;
        }
    }

    /**
     * Удаляем значения 
     */
    private function _clear_rate() {
        $this->rating_id = NULL;
        $this->rate = NULL;
        $this->voted = NULL;
        $this->active = NULL;
    }

}

?>



Как теперь с эти работать.
В контроллере загрузим нашу модель
$this->load->model(‘rating’);
При загрузке выполнится конструктор и проверит указан ли таблица.

Далее мы можем создать оценку или найти ее.
Если мы используем данный объект в админке и хотим например для вновь созданой статьи добавить оценку, мы просто инициализируем нашу модель
и создаем оценку:


   $this->load->model('rating');
   $this->rating->create();

В случае успеха $this->rating->create() вернет true и обновит данные внутри объекта, если же создать не удалось, то вернет false
как пример использования:


        $this->load->model(‘rating’);

        if($this->rating->create()) {
echo ‘Оценка создана’;
        } else {
echo ‘Не получилось создать оценку’;
        }

После того, как мы создали объект мы можем получить данные о нем обратившись:
$this->rating->rating_id – получим ид созданой оценки
$this->rating->rate – Текущая общая оценка
$this->rating->voted – Кол-во проголосовавших
$this->rating->active – активна или нет

Так же мы можем создавать оценку с уже готовыми параметрами
$this->rating->create(оценку, кол-во проголосовавших, активна или нет)

После того как создали объект мы можем передать $this->rating->rating_id в нужную нам модель.
Например у нас есть модель article и в ней есть возможность к статье прикрепить оценку вызвав (article->add_rating($id_raing))
как пример:


       $this->load->model(‘rating’);
       $this->load->model(‘article’);

       if($this->rating->create()) {
$this->article->add_rating($this->rating->rating_id);
       }

Как получить нам нашу оценку, наша модель article вернула нам id оценки теперь мы с помощью find_by_id можем получить объект оценку.
Пример:


$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->find_by_id($rating_id)) {
echo 'Средняя оценка: '.$this->rating->rate;
echo 'Проголосовало: '.$this->rating->voted;
}

Учтите, что find_by_id ищет оценку только ту у которой параметр active = TRUE, если вы хотите искать по всем оценками, то добавьте второй парамметр
$this->rating->find_by_id($rating_id,false);

Редактирование оценки, допустим мы получили оценку и хотим ее сделать не активной, обнулив полностью, тогда код будет такой:


$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->find_by_id($rating_id)) {
$this->rating->rate = 0;
$this->rating->voted = 0;
$this->rating->active = false;
if($this->rating->edit()) {
echo 'Данные обновлены';
}
}

Добавление оценки, тут наверно оптимальней использовать ajax и контроллер, который это буедт обрабатовать:


public function add_rating($id, $paramm ) { //тут всякие проверки и пр $this->load->model(‘rating’); if($this->rating->add_rate($paramm,$id)) { echo ‘Обновленная оценка’; echo ‘Средняя оценка: ‘.$this->rating->rate; echo ‘Проголосовало: ‘.$this->rating->voted; }
}

если мы просто хотим обновить оценку без обновления данных в объекте, то нужно указать 3 параметр в false
$this->rating->add_rate($paramm,$id,false) просто запишет обновленные данные в базу, сам объект обновлятся не будет.
Так же можно получить объект и добавить оценку:


$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->find_by_id($rating_id)) {
$this->rating->add_rate($paramm);
}

Ну практически и все, так же нашу оценку можно удалить вызвав перед этим find_by_id или указав id оценки
пример с id:


$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->find_by_id($rating_id)) {
if($this->rating->delete()) echo 'Удален..';
}

Или же:


$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->delete($rating_id)) echo 'Удален..';

Настройка tftpd для автозагрузки настроек по dhcp в Cisco Ip Phone

Ставим tftpd и xinetd


sudo apt-get install xinetd tftpd tftp

Создаем конфиг для tftpd


touch /etc/xinetd.d/tftpd

И приводим его к следующему виду


service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
# Пользователь от которого запускаем
        user                    = nobody 
        server                  = /usr/sbin/in.tftpd
# Директория корневая tftpd
        server_args             = /var/lib/tftpboot
        disable                 = no
# Тут пишем с какого интерфейса принимаем у меня только с локалки, если наодо со всех то делаем 0.0.0.0
        bind                    = 192.168.1.1
}

Создаем если нету директорию tftpd


mkdrip -p /var/lib/tftpboot

И выставляем права


chown nobody -R /var/lib/tftpboot
chmod 777 -R /var/lib/tftpboot

Перезагружаем xinetd


/etc/inet.d/xinetd restart

ставим dhcpd сервер


sudo apt-get install dhcp3-server

правим конфиг


vim /etc/dhcp3/dhcpd.conf

Нам надо 2 опции в обеих указываем адрес нашего tftp server’a:


option voip-tftp-server code 150 = string;
option voip-tftp-server “tftp://192.168.1.1”;
option voip-tftp-server66 code 66 = string;
option voip-tftp-server66 “tftp://192.168.1.1”;

теперь смотрим syslog туда пишет tftpd, при подключение cisco phone обращается по tftp туда за файлом конфигурации
для просмотра пишем:


cat /var/log/syslog | grep tftp

Нас интересуют строчки типа такой:
trying to get file: /Cisco/SPA303/1cce73d22928.cfg
Из строки видно обращение за конфиг файлом по указанному пути.
Теперь нам осталось только создать папку Cisco/SPA303 для этого пишем


cd /var/lib/tftpboot
#переходи м в корень tftpd
mkdir -p Cisco/SPA303
#создаем папку для конфигов данной модели
touch 1cce73d22928.cfg
#создаем конфиг файл

Теперь приводим настройки конфиг файла к следующему виду, тут даны по минимуму настройки




SADMINBLOG
192.168.1.1
1111
Yes
w234WErq
1111

Station_Display_Name – будет отбражать на дисплее телефона имя
Proxy_1_ – адрес сервера asterisk
User_ID_1_ – ид наш
Use_Auth_ID_1_ – использовать для авторизации Auth_ID_1_
Password_1_ – наш пароль

Тут все в минимальных настройках, ip телефон получит по dhcp, самое простое для создания конфиг файла
это настроить ваш cisco фон через web интерфейс, а потом просто зайти по http://ip-address-cisco-phon’a/admin/spacfg.xml
и перенести из этой xml нужные настройки в файл.

Если что-то не будет работать, то ставим syslog server, я скачал на комп виндовый и в веб интерфейсе циски указываем syslog server
и смотрим логи