суббота, 18 декабря 2010 г.

Spree + webmoney

Сприи в россии не хватало приема вебманей.
Теперь все просто.
Ставим плагин https://github.com/pronix/spree_webmoney
В Gemfile прописываем
gem "spree_webmoney", :git => "git://github.com/pronix/spree_webmoney.git"

Запускаем:
bundle install
rake spree_webmoney:install
И готово. Регистрируйтесь мерчантом в вебмани и принимайте платежи.

четверг, 11 ноября 2010 г.

Random ActiveRecord row:

Model.first(:offset => rand(Model.count))

суббота, 6 ноября 2010 г.

tranz

Быстро добавляем платежные системы и транзакции в проект
https://github.com/pronix/tranz

Ставим плагин

rails plugin install git://github.com/pronix/tranz.git
rails g tranz

Если все получилось удачно - то удаляем плагин

rails plugin remove tranz

воскресенье, 31 октября 2010 г.

Подтверждение карточки на амазоне

Решил бекапы на амазон положить.
Зарегистрировался и карточку кредитную добавил.
Как и всякий забугорный сервис - русских перепроверяет.
Просят факс отправить , либо написать ,что факса нет тогда они придумают другой способ.
Три раза спросили отправить факс.
Три раза я написал , что факса нет.
В итоге - написал "are you stupid ? i haven't fax."
И все - аккаунт активировали :)

пятница, 22 октября 2010 г.

piwik vs analytics

Сбор аналитики на всех новых, и по мере сил на старых проектах будет собираться с помощью piwik.
Гугловский ананлитикс тормозной и бестолковый.
А с пивиком я получаю статистику в реальном времени, о каждом действии пользователя.
Возможность сторонним программам использовать его апи и писать свой скрипт сбора статистики.
Короче гугланалитикс - отстой

среда, 20 октября 2010 г.

простенький автообзвон


require 'rubygems'
require 'erubis'
AST_SOUND_PATH='/var/spool/asterisk/outgoing/'

%w( 0965970142 ).each do |phone|
template = Erubis::Eruby.new <<-EOF Channel: SIP/sipnet/38<%=p%>
Callerid: 7645060
MaxRetries: 2
RetryTime: 20
WaitTime: 60
Context: play_file
Extension: s
Priority: 1
EOF
File.open("#{AST_SOUND_PATH}#{phone}.call", 'w').chown(498,496)
File.open("#{AST_SOUND_PATH}#{phone}.call",'w') {|f|
f.puts template.result( :p => phone)
}
end
# end loop


суббота, 9 октября 2010 г.

defer for javascript_include_tag

Причин не использовать defer (отрисовку страницы не дожидаясь загрузки элементов src с данным тегом).
Первый порыв писать патчик был высмеян после изучения кода contant_tag.
Уже все есть.

= javascript_include_tag %w(application.js jquery.min.js jquery.progressbar.min.js rails.js) , :defer => true


летающий фонарик

C братом Григорием(6 лет) решили сделать летающий фонарик.
Взлетел ,как сказал Гринька , летающий мусорный бак.
Делали фонарик из 120л мешка для мусора, проволки и пропарафиненой газеты.
Взлетел хорошо, но газету надо парафинить больше и распорки из проволки делать длиннее - а то мешок чуть-чуть поплавился.
В планах летающий "мусорный бак" ночью - вдруг светится будет.

воскресенье, 3 октября 2010 г.

require

Ищется файл тут $LOAD_PATH
Добавить директорию $LOAD_PATH << "/path"

вторник, 28 сентября 2010 г.

Кодировка субтитров в mplayer

Явно указываем mplayer -subcp cp1251

суббота, 25 сентября 2010 г.

authlogic create user without session

Понадобилось создавать пользователя без создания сессии.

В authlogic за это отвечает библиотека acts_as_authentic

И метод save_without_session_maintenance



# Save the record and skip session maintenance all together.

def save_without_session_maintenance(*args)

self.skip_session_maintenance = true

result = save(*args)

self.skip_session_maintenance = false

result

end


node.js + couchdb

Использование CouchDB с узлом.js





Apache CouchDB это документ-ориентировочная база данных, которая может делать запросы

и индексироваться в стиле MapReduce, используя JavaScript. CouchDB также предлагает пошаговую репликацию

с двусторонним обнаружением конфликта и его разрешением.



Для начала установите CouchDB.Вы можете скачать CouchDB здесь.

Следующи шаг - установите npm, потому что все клевые пакеты node - в npm:)

Node имеет поддержку в HTTP лучше, чем любой язык, с которым я когда-либо работал и по совпадению интерфейс CouchDB

доступен исключительно через HTTP. Для начала, давайте просто познакомимся с CouchDB, используя HTTP библиотеку и позже

мы посмотрим на некоторые высшие абстракции.





Знакомство с CouchDB, используя запрос



npm install request



Это упрощенный клиент HTTP, который находится в довольно широком использовании среди разработчиков node.Давайте получим

список всех баз данных в вашем CouchDB.





var sys = require('sys')

, request = require('request')

, h = {accept:'application/json', 'content-type':'application/json'}

;

request({uri:'http://myname.couchone.com:5984/_all_dbs', headers:h}, function (err, response, body) {

console.log(sys.inspect(JSON.parse(body)));

})



Если ваш CouchDB - только что установленный, вы увидете что-нибудь подобное этому.

[ '_users' ]



Сейчас давайте создадим базу данных. Вы можете легко зделать это в Futon, веб интерфейсе для CouchDB, но веселей будет зделать

это в node.

request({uri:'http://myname.couchone.com:5984/dbname', method:'PUT', headers:h}, function (err, response, body) {

if (err) throw err;

if (response.statusCode !== 201) throw new Error("Could not create database. "+body);

})



Код ошибки фактически является ошибоками из HTTP клиента. Ни один правильный HTTP ответ не будет иметь

кода ошибки, поэтому если вы хотите проверить правильность созданной базы данных, нам нужно проверить код ответа.



Если вы вышли из режима Админ и создали админскую учетную запись (что вы должны сделать)

вы получите ошибку в которой говориться о том что вам нужно быть админом для того чтобы создавать новые базы данных

Авторизация типа basic поддерживаеться в CouchDB и в запросе, так что мы только добавим их к url.

request({uri:'http://myaccount:password@myname.couchone.com:5984/dbname', method:'PUT', headers:h}, function (err, response, body) {

if (err) throw err;

if (response.statusCode !== 201) throw "Could not create database. "+body;

})



все просто.

Сейчас давайте создадим и получим несколько документов

var dburi = 'http://myaccount:password@myname.couchone.com:5984/dbname'

request({uri:dburi, method:'POST', body:JSON.stringify({data:'somedata'})}, function (err, resp, b) {

if (err) throw err;

if (resp.statusCode !== 201) throw new Error("Could not create document. "+b);

console.log(b);

})



Вы увидете в console print что-нибудь подобное этому.

{"id":"8s7dhf8s7dah8f7sdf8dh", "rev":"1-7sdfy87s", seq:1}



Поскольку мы не имели id для этого документа, мы сделали POST к dburi и это создало новое id для нас. Если мы имеем

что-нибудь, что уже имеет определенный id, подобно тому мы имеем JSON тело твита от твитера API, мы

должны использовать id и использовать вызов PUT.

tweet._id = 'twitter-'+tweet.id

request({uri:dburi+'/'+tweet._id, method:'PUT', body:JSON.stringify(tweet)}, function (err, resp, b) {

if (err) throw err;

if (resp.statusCode !== 201) throw new Error("Could not create document. "+b);

console.log(b);

})



И мы должны увидеть чтото вроде етого

{"id":"twitter-192837218", "rev":"1-3dfy87s", seq:2}



Мы можем получить етот документ запросом GET

request({uri:dburi+'/twitter-192837218'}, function (err, resp, b) {

if (err) throw err;

if (resp.statusCode !== 200) throw new Error("Could not get document. "+b);

console.log(sys.inspect(JSON.parse(b)));

})



Или мы можем получить множество документов используя all_docs api.

request({uri:dburi+'/_all_docs?startkey="twitter-"&endkey="twitter-ZZZ"&include_docs=true'}, function (err, resp, b) {

if (err) throw err;

if (resp.statusCode !== 200) throw new Error("Could not get document. "+b);

console.log(sys.inspect(JSON.parse(b)));

})



all_docs API также позволяет фильтрацию startkey и endkey параметров на id, так что запрос подобно этому только даст нам

обратно документы твитера.



Для создания индексов и запрашивания их, я рекомендую вам почитать O'Reilly's CouchDB The Definitive Guide где всё доступно

изложено.





Знакомство с CouchDB, используя node-couchdb



Для некоторых людей прямое использование HTTP API может быть немного долговатым.существует 4 или 5 node библиотек которые

предоставляют высшие абстракции, но только у меня есть время говорить про node-couchdb.



создавать db просто

var couchdb = require('node-couchdb/lib/couchdb')

client = couchdb.createClient(5984, 'myname.couchone.com'),

db = client.db('my-db');

db.exists(function (err, exists) {

if (!exists) db.create();

})



создавать документ так же просто

db.saveDoc('my-doc', {awesome: 'couch fun'}, function(er, ok) {

if (er) throw new Error(JSON.stringify(er));

console.log('Saved my first doc to the couch!');

});

получить документ еще проще

db.getDoc('my-doc', function(er, doc) {

if (er) throw new Error(JSON.stringify(er));

console.log('Fetched my new doc from couch:');

console.log(doc);

});



Получить все документы - еще про... паждите паждите ... ще!

db.allDocs(function (err, resp) {

...

})

db.allDocs({startkey:'twitter-', endkey:'twitter-ZZZ'}, function (err, resp) {

...

})





Знакомство с couch используя creationix's couch-client



Tim Caswell только что запустил свой собственный клиент CouchDB и начал выполнять инструкции приведенные ниже.

модуль couch-client ето гибрид между http помощником запросов и полностью абстрактным драйвером базы данных.



подключение к базе данных простое

var CouchClient = require('couch-client');

var Users = CouchClient("http://username:password@yourhost:5984/users");



Если база данных не существует вы получите ошибки, но это легко сделать с помощью выставленой функцией request

Users.request("PUT", "/users", function (err, result) {

});



как видите, вы можете зделать любой произвольный http запрос используя функцию request(). Она располагаеться между 2 и 4 аргументом

CouchClient#request(method, path[, body][, callback])



Если вы оставите повторный вызов, это вернет движение вместо этого. Повторный вызов, если указано получают два аргумента

callback(err, result). err исключительный обьект если чтото пошло не так.

result ответ от couch уже JSON.parseed



так же для лучшего представления,couch-client имеет несколько utility функций которые исполнят общие задачи со всеми красиво

представлеными встроеными штуками.Это имеет соединение объединяющее, http keep-alive, и соединение запроса используя couch's bulk APIs



* CouchClient#save(doc, callback) -сохранить документ

* CouchClient#get(key, callback) -получить документ

* CouchClient#remove(key/doc, callback) -удалить документ

* CouchClient@changes(since, callback) -наблюдения за изменениями во всей базе данных с since and вызовы callback один раз за именение (експерементально)


rails3 country_select_tag

В некоторых плагинах,хелперах оставшихся от второй рельсы надо отключать экранирование кода.

content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)

вот значение escape по умолчанию стоит true - тогда как для вывода кода надо false

например в country_select_tag я сделал так

content_tag(:select, countries, options.merge(:id => "#{@object_name}_#{@method_name}", :name => "#{@object_name}[#{@method_name}]"),false)

spree+bluehost

То что в россии нормального хостинга нет все надеюсь знают.

Потому ставим рельсовое приложение на хостинг bluehost

Для начала надо активировать ssh на своем аккаунте - для этого создается тикет и прикладывается
скан паспорта(у меня прокатил скан старого паспорта - они может и не смотрели на него)

Затем ставим все необходимые гемы:

качаем архив сприи http://github.com/railsdog/spree/tarball/v0.11.0

распаковываем tar -xzvf ./имя_архива.tgz

заходим в него и ставим гемы rake gems:install

Запускаем gem env

Находим GEM PATHS оно будет такое /home2/username/ruby/gems

вписываем в "echo 'export GEM_PATH=/home2/username/ruby/gems' >> ~/.bashrc "

перелогиниваемся или вызываем export GEM_PATH=/home2/username/ruby/gems


ставим недоставющие гемы gem install rack -v '=1.1.0' --no-ri --no-rdoc

добавляем в config/environment.rb гемы less treetop mutter и прописываем окружение production

распаковываем все гемы rake gems:unpack


дальше создаем базу и забиваем необходимыми данными и по желанию тестовыми rake db:bootstrap RAILS_ENV=production



делаем симлинк ln -s ~/spree/public ~/public_html

создаем файл .htaccess

AddHandler fcgid-script .fcgi

RewriteEngine On

RewriteRule ^$ index.html [QSA]

RewriteRule ^([^.]+)/!$ $1.html [QSA]

RewriteCond %{REQUEST_FILENAME} !-f

RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

ErrorDocument 500 "Application error Application failed to start properly"


Дальше надо отключить редирект на https при входе в админку и при регистрации

Spree::Config[:allow_ssl_in_production]

>> true

Spree::Config.set(:allow_ssl_in_production => false)


проверяем Spree::Config[:allow_ssl_in_production] должно показать false

все - теперь должно работать

recaptcha + rails3

Рекаптча перестала работать в третей рельсе.

Выводится html и js как текст.

А дело в том что секурность рельсы значительно возросла и что б из переменно вставить js в страницу надо это явно указать.

<%= raw recaptcha_tags %>

spree-ebsin

Есть у индусов такая платежная система ebs.in
И им хочется использовать ее вместе со сприи
= EBS Gateway

EBS Payment Gateway Extension (www.ebs.in)

Install and configure extension preferences:

* preference account_id = Get from your account
* preference url = https://secure.ebs.in/pg/ma/sale/pay/
* preference secret_key = Get from your account
* preference mode = 'LIVE' or 'TEST'
* preference currency_code = 'INR'

You can see messages plugin in the application log:

EBS payment authorized on order R374461356

PaymentID = 1190148
Mode = TEST
DateCreated = 2010-08-19 08:55:48
ResponseCode = 0
MerchantRefNo = R374461356
Amount = 62.00
TransactionID = 2288126
ResponseMessage = Transaction Successful

spree-ebsin

spree-quick-auction

Для товаров задаем цены от х до у
Тот кто первый покупает подешевле.
Финт в том что самые дешевые можно ставить уже якобы проданными.
http://github.com/pronix/spree-quick-auction

spree-firstdata

Установка:

Скопировать firstdata_payment_gateway в папку
vendor/extensions и перезапустить spree.
spree-firstdata

Использование "and" и "or" в руби

Если вы достаточно долго используете ruby, вы откроете для себя and и or операторы.

На первый взгляд это просто синонимы && и ||.

Есть любители использовать буквы, есть любители символов(надо ж показать что вы их знаете),HO надо понимать разницу между ними.

В итоге "and" "or" не ведут себя, как и их символическое родственников. В частности, они имеют гораздо более низкий приоритет.

На данный момент, вы можете матюгнуться если это покажется слишком запутанным.

А если использовать оба варианта то код становится запутанным.

Вообще поведение and и or (как и многое в руби) уходит корнями в перл.

В перле они использовались как операторы if и unless.
Например так:

do_something() or die "It didn't work!";

Эти же операторы в руби преследуют ту же цель.
Для начала "and" и "or" не булёвые операторы, они переключают путь выполнения программы.

and

And используется для цепочек связанных операций когда одна из них может вернуть nil или false.

Пример:

` post = Post.find_by_name(name) and post.publish! `

Тут пост будет опубликован если он найден.

Чем отличается &&? Давайте экспериментировать.
` foo = 42 && foo/2 `

`NoMethodError: undefined method /' for nil:NilClass`
` from (irb):18`
` from :0`

И что же тут случилось ?
Скобочки помогут раскрыть тайну:

`foo = (42 && foo)/2`

Ожидали мы немного другое поведение(теперь-то уже понятно что ожидать такого больше не будем)

`foo = 42 and foo / 2 => 21 `

…другое дело, все как надо выполнилось.

Другой пример

1. next if widget = widgets.pop

Станет:

` widget = widgets.pop and next `


OR

or используется в тех же цепочках операций.
Лучший способ понять эту конструкцию - серия неудачных операций: попробуй способ 1 -> ошибка -> тогда попробуй способ 2 и т.д.
Пример:


` foo = get_foo() or raise "Could not find foo!" `

Пример рефакторинга.
было:

` raise "Not ready!" unless ready_to_rock? `

стало:

` ready_to_rock? or raise "Not ready!" `


Вывод: and и && так же как or и || абсолютно разные инструменты. Использовать надо каждый в своем случае.

asset_host

Если ваше приложение и статические файлы находятся на одном домене,

то броузер с сервером будут обмениваться печеньками(cookies),

что вызовет лишнюю нагрузку на канал.


Яху советует нам всем использовать разные субдомены для статики и приложения.

В итоге все будет работать быстро и потреблять ресурсов меньше.

В рельсе для этого есть параметр asset_host (лучше его использовать только в production окружении).


_config.action_controller.asset_host = "http://assets.ipronix.ru"
_

И конечно надо настроить nginx


_server {
_
_ listen 80;
_
_ server_name assets.ipronix.com;
_
root /var/www/ipronix.com/production/current/public;

_}
_


После рестарта приложения вы увидите что все стало грузиться с разных субдоменов,

и если попробуете измерить скорость и объем то получите выигрыш в каждом запросе.

четверг, 26 августа 2010 г.

Оптимизация миграций(перевод)

Миграции, по моему мнению, одна из лучших вещей в рельсе.
Но что пользоваться максимально эффективно следует придерживаться след правил.


1. Индексы базы данных
В первую очередь определите индексы для всех внешних ключей и для всех колонок которые вы будете сортировать, по которым будете искать и группировать.
class CreateInvoices ActiveRecord::Migration
  def self.up
    create_table :invoices do |t|
      t.integer :number
      t.integer :year
      t.decimal :total_amount
      t.date :invoice_date
      t.integer :company_id
      t.integer :client_id
      t.timestamps
    end
  end
  def self.down
    drop_table :invoices
  end
end

Это обычная миграция генерируемая стандартной script/generate коммандой.
Теперь добавим индексы для сортируемых полей и ключей.

class CreateInvoices ActiveRecord::Migration
  def self.up
    create_table :invoices do |t|
      t.integer :number
      t.integer :year
      t.decimal :total_amount
      t.date :invoice_date
      t.integer :company_id
      t.integer :client_id
      t.timestamps
    end
  end
  add_index :invoices,:company_id
  add_index :invoices,:client_id
  add_index :invoices,:number
  add_index :invoices,:year
  def self.down
    drop_table :invoices
  end
end

Индексы важны для производительности.
База начинает летать по сравнению со стандартной миграцией.
Есть несколько плагинов которые будут полезны для вашей базы.
* http://github.com/eladmeidar/rails_indexes
* http://github.com/mlomnicki/automatic_foreign_key
* http://github.com/samdanavia/ambitious_query_indexer


2. Пишите сиды.
Начиная с рельсы 2.3.4 вместо того что б вписывать данные в миграции - пишите их в seed.rb
Обращаю внимание - фикстуры для тестов,сиды для продакшена(содержит данные без которых нельзя стартануть- например список странн или список станций метро)

обход callback в рельсе

1: не в курсе как обновить атрибуты и сохранить модельку без валидации?
2: u.attributes = {:tt => 12, :yu => 78} u.save(false)
1: пасиба, а не в курсе как избежать before/after коллбеков?
2: вроде как то отключать можно
1: @user_profile.send(:update_without_callbacks)

понедельник, 2 августа 2010 г.

обход callback в рельсе

1: не в курсе как обновить атрибуты и сохранить модельку без валидации?
2: u.attributes = {:tt => 12, :yu => 78} u.save(false)
1: пасиба, а не в курсе как избежать before/after коллбеков?
2: вроде как то отключать можно
1: @user_profile.send(:update_without_callbacks)

четверг, 29 июля 2010 г.

Персер товаров из Amazon

Встала задача получить все товары с амазона (http://amazon.com) у определенной фирмы - Firma Title.
На сайте амазона есть возможность поиска товаров также и у определенной фирмы.
Все бы ничего - бери парсер - парси результаты поиска товаров и в свою базу, но не тут то было...
Оказывается у амазона жестко прописано ограничение на кол-во страниц результатов поиска - 400 страниц, даже если мы видим, что товаров более 27000 физически мы не можем просмотреть далее 400-ой страницы.
сначала был написан небольшой парсер с помощью средств jruby и celerity - но тако решение оказалось слишком долгим в эксплуатации - 2000 товаров заливались примерно за 5 часов - очень долго. Было найдено более быстрое решение - использовать готовое решение для получения результатов поиска товаров - gem ruby-aws.
Напрмер в этой вариации: http://github.com/res0nat0r/ruby-aws

Отрывок из кода:

is = ItemSearch.new( 'Tools', { 'Title' => "Firma title #{keyword}" } )
req = Request.new
req.locale = 'us'
resp = req.search(is, :ALL_PAGES)

Тут мы делаем запрос на получение товаров из категории Tools, содержащих в названии слова CRL и ключевое слово для сужение результатов поиска (помним про злополучные 400 страниц)

items = resp.collect { |r| r.item_search_response[0].items[0].item }.flatten rescue resp.item_search_response[0].items[0].item
puts "Найдено #{items.size} товаров"
И получаем массив товаров.

items.each do |item|
limit += 1
#return "Загрузка окончена" if limit > 5
attribs = item.item_attributes[0]
title = attribs.title.to_s
asin = item.asin.to_s
price = item.offer_summary[0].lowest_new_price.formatted_price.to_s.gsub('$', '') rescue "Не указано"
url = item.detail_page_url.to_s
description = item.editorial_reviews[0].editorial_review.content.to_s
unless Product.find_by_catalogn(asin)
Product.create!(:name => title,
:description => description,
:price_orig => price,
:price => AmazonPrice.calculate(price),
:url => url,
:catalogn => asin,
:status => 'new')
puts "Новый товар: #{title}"
end
end
puts "После запроса CRL #{keyword} в базе #{Product.all.size} товар(ов)"

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

keywords = ["rail", "door", "pack", "tool", "security", "bar", "push", "rod", "aluminium", "storm", "screen", "panel", "package", "automatic", "mirror", "pull", "indicator", "window", "glass", "display", "system", "sliding", "trailer", "box", "bronze", "nickel", "toyota", "mazda", "isuzu", "jeep"]

keywords.each do |keyword|
puts start = Time.now
is = ItemSearch.new( 'Tools', { 'Title' => "CRL #{keyword}" } )
.......

На моем слабом компе товары в кол-ве 3985 шт залились примерно за 25 минут - что ж - уже лучше.

воскресенье, 4 июля 2010 г.

undefined method `each' Fixnum

Ошибка в passenger

Exception NoMethodError in application (undefined method `each' for 417322:Fixnum) (process 13490):
from /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/rack/request_handler.rb:100:in `process_request'
from /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/rack/request_handler.rb:96:in `each'
from /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/rack/request_handler.rb:96:in `process_request'
from /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_request_handler.rb:207:in `main_loop'


Оказывается число пассажир не может обработать
решается таким патчем


diff --git a/lib/phusion_passenger/rack/request_handler.rb b/lib/phusion_passenger/rack/request_handler.rb
index ad22dfa..2b6e60a 100644
--- a/lib/phusion_passenger/rack/request_handler.rb
+++ b/lib/phusion_passenger/rack/request_handler.rb
@@ -96,6 +96,8 @@ protected
headers.each do |key, values|
if values.is_a?(String)
values = values.split("\n")
+ elsif values.is_a?(Fixnum)
+ values = values.to_a
end
values.each do |value|
output.write("#{key}: #{value}#{CRLF}")

четверг, 3 июня 2010 г.

глобальное отключени комментов в openx

В openx по умолчанию в код баннера добавляется комментарий.
При ручной генерации есть возможность его отключить, а вот используя апи такой возможности нет.
Глобального отключения можно добиться изменив в файле
lib/OX/Extension/invocationTags/InvocationTagsOptions.php

строку номер 63 с
'comments' => 1
на
'comments' => 0

вторник, 1 июня 2010 г.

Цели и задачи блога

Блог предназначен для корпортивного общения и обмена опытом по разработке web-ориентированных приложений
Для реализации поставленных задач команда pronix использует в свой работы самые передовые web-технологии:
Языки: ruby, javascript
Фреймворки: Ruby on Rails, JQuery
... и многие другие
Периодически появляются новые вакансии на должности web-разработчиков.
Уверен, что тебе это по силам? Тут ссылка на полное описнаие инструментов и технологий
Тогда Welcome to the Club!

понедельник, 12 апреля 2010 г.

duplicate key value violates unique constraint

PGError: ERROR: duplicate key value violates unique constraint "lastsearches_pkey"

Фиксим выполнив
select setval('lastsearches_id_seq', (select max(id) + 1 from lastsearches));
И все - заработало.
Еще один вариант REINDEX INDEX lastsearches_pkey;

обезьяний патчик

начала валиться ошибка

dima@~/project/mp3cms$ rake db:migrate --trace
(in /home/dima/project/mp3cms)
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
rake aborted!
cannot remove Object::ClassMethods
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:603:in `remove_const'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:603:in `remove_constant'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:603:in `instance_eval'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:603:in `remove_constant'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:549:in `new_constants_in'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_suppor/dependencies.rb:549:in `each'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:549:in `new_constants_in'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:156:in `require'


все перепробовал

В итоге тупо не делаем действие при Object::ClassMethods
unless names.last.to_s =~ /ClassMethods/
parent।instance_eval { remove_const names।last }
end


Оказывается вся проблема в delayed_job второй версии
после сноса версии 2.0.2 и установке 1.8.5 все прекрасно заработало

воскресенье, 14 февраля 2010 г.

snmp - disk space

Получение описания диска


пример1:
/usr/bin/snmpget -t 1 -r 5 -m ALL -v 1 -c строка_пароль monitored.com:161 host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageDescr.1
результат
HOST-RESOURCES-MIB::hrStorageDescr.1 = STRING: Memory Buffers
пример2:
/usr/bin/snmpget -t 1 -r 5 -m ALL -v 1 -c строка_пароль monitored.com:161 host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageDescr.4
результат
HOST-RESOURCES-MIB::hrStorageDescr.4 = STRING: /
Последняя цифра - номер устройства.

Получение общее количества блоков на разделе:


пример:
/usr/bin/snmpget -t 1 -r 5 -m ALL -v 1 -c строка_пароль monitored.com:161 host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageSize.4
результат
HOST-RESOURCES-MIB::hrStorageSize.4 = INTEGER: 176889164
Получени размера блоков
/usr/bin/snmpget -t 1 -r 5 -m ALL -v 1 -c строка_пароль monitored.com:161 host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageAllocationUnits.4
результат
HOST-RESOURCES-MIB::hrStorageAllocationUnits.4 = INTEGER: 4096 Bytes
В итоге можно посчитать размер в мегабайтах раздела
176889164*4096/1024**2=690973Mb
И последнее - сколько блоков занято информацией
/usr/bin/snmpget -t 1 -r 5 -m ALL -v 1 -c строка_пароль monitored.com:161 host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageUsed.4

watir+facebook status

Как поменять статус в facebook используя watir


>> @b.class # непосредственно броузер после входа в свой аккаунт
=> Celerity::Browser
>> @b.text_field(:name,'status').value = 'мой новый статус'
=> "\320\260\321"
>> @b.text_field(:name,'status').focus
=> nil
>> @b.button(:class,'UIButton_Text').click


и новый статус готов.









We use metatrader4 - the best forex trading platform and I enjoy it.