Showing posts with label интернет. Show all posts
Showing posts with label интернет. Show all posts

Tuesday, May 12, 2009

Wednesday, April 1, 2009

Links: tddspry, ItQuest.ru

Link 1. tddspry

Что такое tddspry? Это небольшой набор утилит для тестирования django-приложений с помощью nosetests. Если по какой-то причине Вы не можете воспользоваться Django Test-execution Framework или джанговские тесты просто Вас раздражают, то обязательно обратите внимание на этот небольшой проект. На данный момент в состав tddspry включены хэлперы для написания тестов, а также моки для БД и twill. В дальнейшем возможно включение поддержки Windmill, etc. Проект открыт для предложений. :)
Пример использования:
class TestUI(TwillMock, DbMock):
def setup(self):
super(TestUI,self).setup()
login_to_admin(username='admin', password='admin')

@show_on_error
def test_order_add_no_transport(self): # ticket:9
go(SITE + '/shop/order/add/')
code(200)
assert not "Transport" in show(), show()

Link 2. ItQuest.ru

Возможно, многие из читателей уже слышали о таком сервисе, как ItQuest.ru. А если не слышали - обязательно обратите на него внимание. Ресурс идейно схож с StackOverflow - большая база вопросов и ответов на IT тематику. Так что если у Вас есть вопрос, ответ на который не знает даже Google, попробуйте задать его здесь.
P.S. Сайт написан на Django. Еще один повод присмотреться.

Thursday, August 28, 2008

IPv6 не будет

Слегка адаптированная мной заметка по мотивам http://www.extremetech.com/article2/0,2845,2328258,00.asp:

Arbor Networks измерили объем IPv6 траффика, проходящего через 2400 бэкбонов и роутеров у 87 провайдеров Интернет по всему миру. Учет велся с Июня 2007 по Июль 2008 года. Полученные данные были использованы для исследования, которое компания считает наиболее всеохватывающим исследованием ситуации с IPv6 на сегодняшнее время. В целом Arbor отследил 15 экзабайт траффика - при этом все человеческое знание занимает 4 экзабайта, как заявляют представители компании.

Это исследование показало, насколько плачевна ситуация в стане IPv6. Если верить полученным данным, объем междоменного IPv6 траффика составил всего 0.0026% от объема IPv4 траффика. Были замечены два пика активности между 4 ноября и Рождеством 2007 года, на пике процентное соотношение поднялось до 0.012%. При этом, процент соответствия IPv6 и IPv4 траффика оставался неизменным за все время исследования.

Я уже писал о том, что такое IPv6 и насколько переход на него с устаревшего IPv4 важен. В действительности, если не будет существенных сдвигов в ближайшее время, то по некоторым оценкам уже к 2011 году IPv4 адреса закончатся и развитие сети Интернет остановится. Переход же на IPv6 даст возможность использовать 340 миллиардов миллиардов миллиардов миллиардов адресов, чего должно хватить на ближайшее будущее :)

"Я не думаю, что переход уже начался", - говорит Scott Iekel-Johnson, основной автор исследования и главный специалист по программному обеспечению в компании Arbor, -"Не похоже, что хотя бы в какой-нибудь значительной части из охваченных исследованием регионов были существенные сдвиги"
Как это ни дико, по заявлениям исследователей, один из пиков совпал с собранием рабочей группы проектирования Интернет (IETF) - одной из групп, которая яростно толкает индустрию к использованию IPv6 адресования. Во время собрания, как говорят представители Arbor, участников попросили выключить IPv4 функциональность на своих компьютерах и роутерах и проверить, какие сайты будут доступны. Чтобы протестировать инфраструктуру, они смотрят онлайн-видео, качают файлы больших объемов. Предполагается, что это и вызвало учтенный пик.

Тем не менее, на этом собрании было зарегистрировано только 1168 человек. Т.е., по данным компании, всего чуть более тысячи человек вызвали самый высокий всплеск IPv6 активности за последние 12 месяцев. Это говорит о многом.

Исследователи видят два способа разрешения проблемы. Первый - поддержка идеи компаниями и государственными органами. Второй - проникновение идеи глубоко в массы. Iekel-Johnson делает ставку на первый вариант. Он приводит пример: "Если Comcast(ISP - прим. моё) скажет своим клиентам: 'Окей, вам нужно использовать IPv6, потому что у нас кончаются адреса, а мы хотим добавлять новых пользователей' - это приведет к существенным продвижениям".
Со своей стороны хочется добавить, что это исследование раскрыло мне глаза на то, насколько все плохо с IPv6. Возможно, понимание того, что мы еще в самом начале пути, подстегнет крупные компании, представителей государства и простых пользователей и продвижение пойдет быстрее.
Чтобы избежать обвинения в искажении фактов при адаптации я предлагаю поучаствовать в полном переводе статьи - сам я не смогу довести ее до читабельного вида без существенных правок. Поучаствовать и почитать текущий вариант перевода можно здесь

Friday, June 20, 2008

Использование Google Search API и Google Translate API в Python

Как известно, Google предоставляет множество различных API для доступа к своим сервисам. Список и описание их можно найти здесь. Я же хочу остановиться на двух весьма удобных сервисах от Google - поиске и переводе. Точнее, хочется предложить простенький рецепт по использованию предоставляемых для них API из Python.

Google Search API и Google Translate API представляют собой AJAX API: вызовы функций - это HTTP запросы, ответ возвращается в формате JSON. В связи с последним нам понадобится библиотека simplejson для парсинга ответов. Итак, начнем с перевода.

def translate(text,langpair):
import urllib
import simplejson

query = urllib.urlencode({'q' : text.encode("utf-8"),'langpair':langpair})
url = u'http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&%s'.encode("utf-8") \
% (query)
search_results = urllib.urlopen(url)
json = simplejson.loads(search_results.read())
mess = json['responseData']['translatedText']
return mess

translated = translate("I am feeling lucky","en|ru")
print "Translated:", translated
Не сложнее и API для поиска:
def search(text):
import urllib
import simplejson

query = urllib.urlencode({'q' : text.encode("utf-8")})
url = u'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&%s'.encode("utf-8") \
% (query)
search_results = urllib.urlopen(url)
json = simplejson.loads(search_results.read())
results = json['responseData']['results']
return results

results = search("text to search")
title = results[0]['title']
noh_title = title.replace('', '').replace('', '')
url = results[0]['url']
print noh_title+": "+url # Мне повезет! :)
Для работы API не требуется регистрации, что весьма приятно. Удачного применения!

Wednesday, March 26, 2008

Собственные фильтры в админке django (Custom FilterSpecs)

Обновление от 04.05.2012. Данная статья была написана довольно давно, но до сих пор вызывает некоторый интерес. Спешу сообщить, что с 23-го марта 2012 года с релизом Django 1.4 начинать поиск информации про custom фильтры стоит с официальной документации

Админка django - одна из самых убойных фичей этого фреймворка, как признаются и сами авторы. Она позволяет автоматически подключить к вашему сайту функционал по добавлению, редактированию и изменению как встроенных, так и пользователских моделей. Конечно, если логика добавления и изменения информации слишком сложна, то эта админка не подходит, однако, это не означает, что ее не нужно использовать - она вполне может быть дополнением к существующему функционалу. Представьте, что создавая сайт-блог вы добавили функциональность, которая позволяет быстро создавать и редактировать записи. Но это не мешает вам использовать джанговскую админку, когда вам нужно изменить какие-то параметры записи, которые нельзя изменить иначе(подробней об админке можно прочитать в 6ой главе Djangobook)

Существуют также случаи, когда админка Django предоставляет практически весь функционал, который нужен на сайте. Например, если вам нужно приложение для внутреннего использования, которое показывает сохранённую в базе информацию по каким-нибудь событиям(пример из повседневной жизни :) ), то лучше встроенной админки не найдёшь - можно легко настроить, какие поля показывать, по каким полям вести поиск, по каким фильтровать - и всё это - лишь пара строчек кода!
Фильтры в админке - более чем удобная вещь. Например, если у вас есть поля, которые могут принимать значения из фиксированного набора(успех/не успех, номер ошибки, и т.д.), то фильтры позволяют быстро отфильтровать, например, все "успешные" записи, или все записи с упоминанием ошибки 302. Однако, может случиться, что стандартных наборов фильтров вам не хватит, и вы пожелаете добавить свой собственный.

Я постараюсь показать весь процесс добавления нового фильтра на весьма полезном примере - на фильтре, который позволит фильтровать записи по заданному промежутку времени. Например, если у вас есть поле "Время создания", то можно будет отфильтровать все записи, которые были созданы в промежутке между 25 марта 2008 года 00:00 и 26 марта 2008 года 15:00. Итак, начнём.

Все фильтры, которые есть в админке, расположены в django.contrib.admin.filterspecs, все фильтры являются наследниками FilterSpec, у которого есть два особо интересных метода - create и register. Новый фильтр нужно будет зарегистрировать, вызвав функцию FilterSpec.register(test,factory), где test - это функция, принимающая объект ..Field (фильтры создаются автоматически через интроспекцию существующих полей модели) и возвращающая True, если данный фильтр применим для данного поля, а factory - это обычно класс фильтра. Функция register() просто сохраняет эту пару во внутренний список. Функция create() вызывается, когда для какого-нибудь поля нужно создать фильтр - данная функция просматривает список, запускает test функции, и когда находит подходящий фильтр - использует factory для создания объекта и возвращает его. После объявления класса FilterSpec идут сами фильтры, которые сразу же и регистрируются.
Здесь следует важное замечание: фильтры добавляются в список append'ом, поэтому последний добавленный фильтр и будет при create вызван последним. А так как в уже рассмотренном файлике последним добавляется фильтр, который умеет фильтровать любые поля, что означает, что если мы зарегистрируем новый фильтр, то до него при create просто никогда не дойдёт очередь. Такое поведение мне не очень понятно(я привык, что последние добавленные обработчики обрабатываются первыми:) ), к тому же оно сводит на нет прямолинейные попытки добавить свой собственный фильтр.

Однако есть как минимум два способа обойти это недоразумение:
- Тикет #5883 содержит патч, который меняет порядок добавления. Он очень простой и вполне разумный. Я надеюсь, что когда-нибудь он войдёт в основную ветку :)
- Вместо register() можно вставлять нужную запись напрямую в список: FilterSpec.filter_specs.insert(-1, (test, factory))
Что использовать - ваш выбор. Я для себя выбрал путь патча, ибо хоть второй и не требует изменения кода django, однако он противоречит дзену :)

Разобравшись в том, как регистрировать фильтр, перейдём к тому, как он функционирует. Все фильтры рендерятся через шаблон filters.html (django/contrib/admin/templates/admin/filters.html). Для того, чтобы фильтр нормально отобразился, он должен уметь возвращать список опций выбора(choices), которые и будут отображены автоматически. Естественно, это не подходит для нашей цели(как вы помните, мы пытаемся сделать фильтрование по промежутку времени, для задания этого промежутка нам понадобится два текстовых поля), поэтому мы поменяем поведение шаблона(как подменить шаблон админки на свой можно прочитать всё в той же 6ой главе Djangobook). Текст шаблона filters.html ниже:

{% load admin_list %}
{% load i18n %}
{% load filter_tags %}
{% if cl.has_filters %}<div id="changelist-filter">
<h2>{% trans 'Filter' %} </h2>
{% for spec in cl.filter_specs %}
{% if spec.is_datetime_interval_filter %}
{% datetime_interval_filter cl spec %}
{% else%}
{% filter cl spec %}
{% endif %}
{% endfor %}</div>{% endif %}
Хочется обратить внимания на отличия от стандартного файла - подгружаются filter_tags - именно в нём у нас будет находиться inclusion tag datetime_interval_filter, который будет использоваться для всех фильтров, для которых is_datetime_interval_filter есть True(т.е., для нашего фильтра). Теперь посмотрим на новый тэг:
from django import template
register = template.Library()

@register.inclusion_tag('datetime_interval_filter.html')
def datetime_interval_filter(cl, spec):
return spec.get_output_dict(cl)
Ничего интересного в нём нет - он просто возвращает нужный для рендеринга контекст, оставляя процесс генерации его нашему объекту-наследнику FilterSpec(схожим образом действует и стандартный тэг filter). Как видно, он использует темплейт datetime_interval_filter.html - его текст ниже:
<script language='javascript'>
function set_new_location_{{field_name}}()
{
var lte = document.getElementById("{{field_name}}_lte_edit").value;
var gte = document.getElementById("{{field_name}}_gte_edit").value;
document.location.href = '{{query_str}}&{{field_name}}__gte='+gte+'&{{field_name}}__lte='+lte;
}
</script>
<h3>By {{field_title|escape}}:</h3>
<ul>
<li><input id="{{field_name}}_gte_edit" value="{{gte_old_value}}" /></li>
<li><input id="{{field_name}}_lte_edit" value="{{lte_old_value}}" /></li>
<li><a onClick='javascript:set_new_location_{{field_name}}();' style="cursor:pointer;">Filter</a></li>
</ul>
Что есть в темплейте - для каждого нашего фильтра создаётся небольшой скрипт, который займётся обработкой переходов на новую страницу с отфильтрованными данными. Также выводятся два текстовых поля и ссылка для перехода. Для того, чтобы корректно отрендерить этот темплейт, нужно передать:

field_name - имя поля, по которому будем фильтровать.
query_str - строка запроса, которая может содержать и другие значения фильтров.
field_title - название поля.
gte_old_value/lte_old_value - сохранённые значения текстовых полей. Выводятся в те же поля после применения фильтра, что очень удобно для редактирования.

Вероятно, код можно было бы упростить, если заметить, что функцию можно использовать одну для всех таких фильтров, или еще каким-нибудь образом, но он работает - а это всё, что нужно от клиентской части.

Ну, и наконец, сам объект-фильтр:
from django.contrib.admin.filterspecs import FilterSpec
from django.utils.encoding import iri_to_uri

class DateFieldIntervalFilterSpec(FilterSpec):
def __init__(self, f, request, params, model):
super(DateFieldIntervalFilterSpec, self).__init__(f, request, params, model)

is_datetime_interval_filter = True

def get_output_dict(self,cl):
p = cl.params.copy()
return {
'field_name': self.field.name,
'query_str': iri_to_uri(cl.get_query_string(remove=["%s__lte"%self.field.name,"%s__gte"%self.field.name])),
'gte_old_value': p.get('%s__gte'%self.field.name,''),
'lte_old_value': p.get('%s__lte'%self.field.name,''),
'field_title':self.field.verbose_name
}
Небольшие пояснения по коду - как я уже говорил выше - мы наследуемся от FilterSpec. Конструктор не представляет никакого интереса. Флажок is_datetime_interval_filter мы уже упоминали - когда рассматривали темплейт filters.html. Единственная функция, которая требует рассмотрения - это get_output_dict(), которая возвращает словарь, используемый для рендеринга конечного html кода. field_name и field_title не представляют особого интереса - мы просто возвращаем имена поля, для которого работает фильтр. query_str мы получаем из объекта ChangeList - это основной объект, который содержит все фильтры, а также предоставляет доступ к нужным этим фильтрам параметрам(найти его можно в django.contrib.admin.views.main). В качестве параметров функции мы передаём список remove - в нём находятся те значения, которые возвращать не нужно, даже если они указаны. Это позволит нам избежать повторений вида &time__lte=smth1&time__lte=smth2. gte_old_value/lte_old_value мы получаем также из ChangeList - из текущих параметров.

После этого осталось зарегистрировать новый шаблон(для тестирования это можно сделать даже в Urlconf, хотя это и может вызвать некоторые проблемы при автоматической перезагрузке девелопмент сервера):
FilterSpec.register(lambda f: isinstance(f, models.DateField),DateFieldIntervalFilterSpec)
Хочу заметить, что я подменяю все DateTimeField(мне откровенно не нравится стандартный фильтр для DateTime), в то время, как можно добавить проверку на наличие у поля дополнительного атрибута, который добавлять только тем полям в модели, для которых нужен такой фильтр.

Ну, и конечно, хотелось бы посмотреть на результат. Вот скриншшот:На скриншоте - сохраненные Cdr events от Asterisk. Если как-нибудь будет время - я постараюсь осветить тот небольшой код, который позволяет сохранять евенты от Астериска в базе - это потрясающая иллюстрация возможностей Python, Django и Twisted.

Буду рад любым фидбекам и исправлениям. :)

Friday, March 21, 2008

Курс «Как стать успешным фрилансером и остаться человеком»

[info]4annel в своем ЖЖ публикует курс статей "Как стать успешным фрилансером и остаться человеком"

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

P.S. Не могу не поделиться - впервые обратил на этот проект чуть больше внимания: Twisted . Посмотрите и вы - это потрясающий фреймворк!

Tuesday, February 26, 2008

Django urlpatterns для hostname

Я не буду сейчас детально рассказывать, что такое urlpatterns в django, понадеясь на осведомлённость возможных читателей. Однако для тех, кому это внове, дам краткий пример. В Django для сопоставления url`ов коду используются конфигурационные файлы urls.py (Urlconf). Основной смысл этих файлов в подобных строчках:

(r'login/$', 'someapp.views.login')
Данная строка означает, что когда пользователь зайдёт на страницу www.example.com/login/ , то для генерации страницы вызовется функция someapp.views.login . В простейшем случаем первым параметром такой строки является регулярка, вторым - нужная функция. Заметьте, что регулярка сопоставляется только с путём, а хостнейм отбрасывается. Сами urlconf весьма удобны, но такое игнорирование хостнейма не даёт использовать стандартные джанговские подходы для реализации подобных вещей:
  • Вызов различных функций в зависимости от части хостнейма, например, pda.example.com - PDA версия сайта, blog.example.com - блог на сайте. Конечно, это можно реализовать и другими средствами, однако создание разветвлённой структуры всё же затруднено.

  • Передача параметров в функции в зависимости от хостнейма. Например, tilarids.blogspot.com - на самом деле, все такие страницы могут генерироваться одной функцией в зависимости от имени пользователя
Т.о., возникает желание получить механизм, который бы работал аналогично urlconf, но вместо пути работал бы с хостнеймом. После небольшого исследования на эту тему у меня создалось впечатление, что это так нигде и не реализовано. Отсюда и родился подобный код:
class HostnameDispatcher(object):
def __init__(self, view, myregex):
self.regex = re.compile(myregex, re.UNICODE)
self.view_func = view
def __call__(self, request, *args, **kwargs):
current_site = RequestSite(request)
match = self.regex.search(current_site.domain)
print "Current args:",args, kwargs
if match:
new_kwargs = match.groupdict()
if new_kwargs:
new_args = args
else:
new_args = match.groups() + args
new_kwargs.update(kwargs);
return self.view_func(request,*new_args,**new_kwargs)

class HostnameRegexPattern(RegexURLPattern):
def __init__(self, regex, callback, hostname_re,proto=u'http://',default_args=None, name=None):
RegexURLPattern.__init__(self,regex,callback,default_args, name)
self.hostname_regex = hostname_re
self.dispatcher = HostnameDispatcher(self.callback, self.hostname_regex)
self.old_regex = self.regex
self.regex = re.compile(u'\b'+proto+hostname_re+u'/'+regex,re.UNICODE)

def resolve(self, path):
match = self.old_regex.search(path)
if match:
kwargs = match.groupdict()
if kwargs:
args = ()
else:
args = match.groups()
kwargs.update(self.default_args)
return self.dispatcher, args, kwargs

Хочется заметить, что основными требованиями к коду были:
  • Полная совместимость со стандартными способами resolve и reverse (получения функции по адресу и адреса по функции соответственно)
  • Безболезненное встраивание в рабочую систему Django
Возможно, код несколько сумбурный - несмотря на недолгую жизнь, он успел почувствовать на себе процесс развития и переделывания. Постараюсь объяснить, что здесь зачем. Итак:
  • HostnameDispatcher - класс, который позволяет resolv`ить функцию по хостнейму, являсь некой надстройкой над этими самими функциями(вернёмся к терминологии django и будем называть их view). Например,
    disp = HostnameDispatcher(my_view,r'^(.*)$')
    создаёт на основе существующего view новый объект, который при резолве добавляет параметры из хостнейма. Удобно, быстро, но никак не поможет при reverse. А вот reverse - это как раз самая сложная, но и не менее нужная часть
  • HostnameRegexPattern - это замена стандартным урлпаттернам. resolve здесь реализуется через уже упомянутый HostnameDispatcher. А вот с reverse пришлось извратиться. В django нет хорошей возможности изменять стандартное поведение reverse. Т.о., я просто изменил существующую регулярку, и в итоге получил почти правильный результат. Единственное, выскакивает '/' в начале. Для его устранения я не придумал ничего лучше, чем сделать небольшой патч для django(в django.core.urlresolvers):
    def backspace_process(func):
    def reverse_new(viewname, urlconf=None, args=None, kwargs=None):
    ret_val = func(viewname, urlconf, args, kwargs)
    if ret_val[:4]=='/%08':
    return ret_val[4:]
    return ret_val
    return reverse_new

    def reverse(viewname, urlconf=None, args=None, kwargs=None):
    args = args or []
    kwargs = kwargs or {}
    return iri_to_uri(u'/' + get_resolver(urlconf).reverse(viewname, *args, **kwargs))

    reverse = backspace_process(reverse)
    Т.е., добавляется в начале отдельный символ(\b), который потом удаляется при надобности. Такое удаление не должно никак повлиять на другие urlpatterns
Ну и наконец: как это использовать. Нет ничего проще- записываем в urls.py в паттерны такую строчку:
HostnameRegexPattern('test/(\d+)/$', 'blog.views.test',r'^(.*)$'),
, где первый параметр - регулярка для пути, второй - функция, третий - регулярка для хостнейма. Всё! :)

Кто может предложить что-нибудь более интересное, или улучшить уже существующий код - буду весьма благодарен.

Friday, January 18, 2008

Django WEB Framework

Не так давно открыл для себя весьма интересный веб-фреймворк для разработки сайтов по концепции MVC - это Django. Радует он хорошо продуманной структурой, документацией, а также выбранным языком программирования - Python обеспечивает ощутимую при разработке мощь. В общем, первое и незабываемое впечатление о Django - этот фреймворк писался для разработчиков, а не для пользователей.

Рекомендую! :)

Monday, October 1, 2007

Folding@Home

В поддержку хорошего дела:

Процесс сворачивания белков, являясь критическим и фундаментальным практически для всей биологии, остается загадкой. Более того, вовсе не удивительно, что когда белки сворачиваются неправильно, могут возникнуть серьезные эффекты, включая многие хорошо известные заболевания, такие как болезнь Альцгеймера, коровье бешенство и другие.

Что же делает Folding@Home? Folding@Home - проект распределенных вычислений, который изучает сворачивание белков, неправильное сворачивание, объединение и связанные с этим заболевания.

Для того, чтобы помочь вычислительной мощностью собственного компьютера, достаточно зайти по этой ссылке и скачать программу(под Windows, Linux, MacOS X).

Friday, September 28, 2007

Проблема с получением каналов Blogger для определенных ярлыков

В соответствии с этим руководством можно получить каналы (Atom, RSS) для любого ярлыка, а не только для всего сайта. Например, можно было бы получить канал, который повзоляет следить только за статьями в этом блоге с ярлыком "программирование".
Например, адрес моего блога:
http://tilarids.blogspot.com
В соответствии с руководством, для того, чтобы получить соответствующий канал, нужно:
1. Взять URL вашего основного канала. Например:
http://tilarids.blogspot.com/feeds/posts/default
2. Добавить к нему "/-/имя_ярлыка". Например, вот так:
http://tilarids.blogspot.com/feeds/posts/default/-/программирование
Внимание! Такой подход может не работать в браузере Mozilla Firefox 2.x, если набирать в адресной строке. По умолчанию Firefox кодирует русский текст не так, как это принято на Blogger. Для того, чтобы можно было распространять ссылку на канал и среди пользователей этого браузера(он автоматически распознает каналы и предлагает подписаться), лучше разместить ссылку у себя в Blogger, тогда по щелчку будет открываться правильная страница. Между прочим, полученный таким образом адрес можно передавать уже без дополнительных ухищрений.
3. В итоге получим ссылку на канал по ярлыку "программирование"

Saturday, September 15, 2007

Электронное общение

"Общественные нормы не поддерживают себя сами - их поддерживают люди, активно, в открытую, публично эти нормы применяющие"(с)
В виртуальной жизни человек ограничен правилами, отличными от правил реальной жизни. Часто не имеет значения ни пол, ни возраст. Лишь слова и мнения. Кроме того, "общественные места" в сети Интернет по большей части доступны каждому - нужно лишь зарегистрироваться.

В результате, участникам общения часто приходится терпеть высказывания людей, которых в реальности не подпустили бы и на 100 метров. Чтобы решить эту проблему было изобретено множество средств(например, модерирование). Но, наверное, самыми удачными оказались социальные сети.

Социальная сеть - это место общения реальных людей в сети. У них есть настоящие имена, фотографии, круг друзей. Каждый пользователь сам решает, с кем ему общаться, а с кем - нет. Задатки социальной сети есть на любом форуме, на многих сайтах знакомств. Но лишь некоторые проекты в сети достойны громкого имени: "Социальная сеть". Среди них(лишь моё мнение):

facebook - наверное, самая большая социальная сеть.
Мой круг - самая большая русскоязычная социальная сеть
Стрелка - весьма удобная(практически - клон facebook) социальная сеть. Ориентирована на Украину, открылась не так давно, но уже имеет множество поклонников.

Friday, September 14, 2007

Размышления о популярности

Когда создаешь блог, то рано или поздно(чаще - рано) у тебя появляется желание сделать его популярным. Многие здесь идут по пути наименьшего сопротивления и создают блоги в системах, подобных LJ. Такие системы обеспечивают достаточный приток читателей, в силу своей популярности и идеи "LJ-friends".
Некоторые используют для ведения блогов социальные сети, на подобие "facebook" или "Мой Круг". Последняя весьма популярна среди русскоязычных пользователей, к тому же обеспечивает интеграцию с LJ.
Те, кто из упрямства идут дальше, в итоге или бросают саму затею, или становятся узниками собственного блога - повсеместно рекламируя его, они постоянно находятся в поисках интересного контента, и забывают, ради чего блог создавался.
Дабы избежать всех этих опасностей, для себя я решил, что мой блог для всех - это тот URL, который они увидели в моём профиле либо резюме; или, в случае интернет-дружбы, получили в процессе IM-общения. Для меня же блог пусть останется местом свободной от оков мысли.