четверг, 29 апреля 2010 г.

C#: Woking with JSON

Потребовалось работать с простейшими JSON объектами в C#, стал искать библиотеку и столкнулся с тем, что большинство библиотек чрезмерно сложны. Мне, всего лишь, надо разобрать строку в Dictionary, и провести обратную операцию. И еще, как это не странно, меня волнует лицензионная чистота.

Нашел библиотечку - JSON, которая полностью меня удовлетворила.

Вот примерчик:
using Procurios.Public;
...
var hash = (Hashtable)JSON.JsonDecode("{\"Completed\":1, \"Indexed\":1}")
if (hash["Completed"]==1)
{
   hash["Indexed"]==0;
   var str = JSON.JsonEncode(hash);
}

вторник, 27 апреля 2010 г.

vkontakte.ru was blocked .blogspot.com :(

Граждане из Вконтакта в конце озвездинели от огромной массы славы и теперь считают что все блоги на blogspot.com потенциально вредоносны и могут обидеть леммингов, которые пользуются вконтактом. Предлагаю пойти дальше и выпустить свою версию браузера, которая будет общаться исключительно с одним единственным правильным сайтом! И правда на кой нам надо весь этот интернет,когда есть сия благая сеть.

--
ВКонтакте | Потенциально вредоносная ссылка

Ссылка, по которой Вы попытались перейти, ведёт на сайт, расположенный на бесплатном хостинге.

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

ВКонтакте всегда заботится о Вашей безопасности!
--

SharePoint 2010 CSOM: How to upload file to folder and set fields

Заливка файлов в Client Object Model и одновременное задание полей мне не сразу дались.
Например вот такой метод для док либ работать не будет:
var clientContext = new ClientContext("http://server2010/sub");
var web = clientContext.Web;
var list = web.Lists.GetByTitle("SuperDocLibWithFields");

var lci = new ListItemCreationInformation();

lci.FolderUrl = "/sub/SuperDocLibWithFields/Folder1";
lci.LeafName = "FileSuper.txt";
lci.UnderlyingObjectType = FileSystemObjectType.File;

var item = list.AddItem(lci);
item.Update();

clientContext.Load(item);
clientContext.ExecuteQuery();

Выдает ошибку: "To add an item to a document library, use SPFileCollection.Add()"

Надо делать вот так:
var clientContext = new ClientContext("http://server2010/sub");

var FileSrvRelUrl = "/sub/SuperDocLibWithFields/Folder1/File3.txt";
using (var fileStream = new MemoryStream(new byte[100]))
{
    Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, FileSrvRelUrl, fileStream, false);
}
var web = clientContext.Web;
var f = web.GetFileByServerRelativeUrl(FileSrvRelUrl);
var item = f.ListItemAllFields;
item["NewCol"] = "Value";
item["Author"] = 66;
item["Editor"] = 67;

item["Created"] = DateTime.Now.AddYears(-10);
item["Modified"] = DateTime.Now.AddYears(-5);
item.Update();
clientContext.Load(item, i=>i.Id);
clientContext.ExecuteQuery();

Console.WriteLine("Item id {0}",item.Id);

SharePoint 2010 CSOM: How to create item in folder in list

Item'ы создавать через Clent Object Model в принципе так же просто как и папки:
var clientContext = new ClientContext("http://server2010/sub");
var web = clientContext.Web;
var list = web.Lists.GetByTitle("SuperContacts");

var lci = new ListItemCreationInformation();

lci.FolderUrl = "/sub/Lists/SuperContacts/TestFolder2";
lci.UnderlyingObjectType = FileSystemObjectType.File;

var item = list.AddItem(lci);
item["Title"] = "Test item 2";
item.Update();

clientContext.Load(item);
clientContext.ExecuteQuery();

У меня сложилось впечатление что ListItemCreationInformation.LeafName на процесс создание item'ов не оказывает.

SharePoint 2010 CSOM: How to create folder in list

Вот так вот создаем папку в листе "SuperContacts" (тип Contacts) и устанавливаем ее время создания,модификации и пользователей которые это делали:
var clientContext = new ClientContext("http://server2010/sub");
var web = clientContext.Web;
var list = web.Lists.GetByTitle("SuperContacts");

var lci = new ListItemCreationInformation();

lci.FolderUrl = "/sub/Lists/SuperContacts";
lci.LeafName = "MyFolder";
lci.UnderlyingObjectType = FileSystemObjectType.Folder;

var item = list.AddItem(lci);
item["Author"] = 66;
item["Editor"] = 67;

item["Created"] = DateTime.Now.AddYears(-10);
item["Modified"] = DateTime.Now.AddYears(-5);

item.Update();

clientContext.Load(item);
clientContext.ExecuteQuery();

Если нужно создать папку в папке то надо всего лишь правильно указать FolderUrl и LeafName:
lci.FolderUrl = "/sub/Lists/SuperContacts/MyFolder";
lci.LeafName = "SubFolder";

Russian voice synthesis service

Наткнулся тут на сайт ЦРТ, который среди прочего занимается синтезом речи.
Весьма скажу неплохо у них это выходит. Вот например синтезированный кусочек песенки.

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

How to post entity to livejournal.com from python

Вот так вот можно постить в ЖЖ на питоне:
import xmlrpclib
import time

ljsrv = xmlrpclib.ServerProxy(r"http://www.livejournal.com/interface/xmlrpc")

curtime = time.localtime()

data = {'ver':0,
 'subject':'test post from xml rpc 2', 
 'year': curtime[0], 
 'mon': curtime[1], 
 'day': curtime[2],
 'hour': curtime[3],
 'min': curtime[4],
 'security': 'private',
 'event': 'test message from xml rpc',
 'username': 'VasyPupkin',
 'password': 'PaSsWoRd',
 }

response = ljsrv.LJ.XMLRPC.postevent(data)

print response

Описание команд LiveJournal API.

воскресенье, 25 апреля 2010 г.

Google Chart Tools

Интересное API от Google позволяющее легко,просто,бесплатно и не занимая собственных ресурсов рисовать графики, диаграммы и всякие чарты.
Вот результат моих экспериментов:
Example of google chart API

суббота, 24 апреля 2010 г.

How to parse RSS or Atom on Python

Набрел на простой питоновский модуль для работы с RSS\Atom - feedparser, понимает кучу модификации этих протоколов.

Вот примерчик парсинга моего блога:
import feedparser

blog = feedparser.parse('http://advard2.blogspot.com/feeds/posts/default')

print 'Title: %s'%blog.feed.title
print 'Desc: %s'%blog.feed.description
print 'Updated: %s'%blog.feed.updated

print 'Posts titles:'
for post in blog.entries:
 print '\t%s'%post.title

четверг, 22 апреля 2010 г.

SharePoint: Select field from item by name. InternalName vs Title.

Часто при работе с SharePoint встречаются конструкции вида:
SPListItem item = List.Items[0];
item["FieldName"] = "Some Value";
И лично мне всегда было непонятно, какое из имен поля можно использовать, т.к. у каждого поля есть аж 3 названия - Title,InternalName и StaticName

Сегодня в рефлекторе наткнулся на кусок кода, который дает ответ на этот вопрос:
internal SPField GetField(string strName, bool bThrowException)
{
    this.EnsureFieldsSafeArray(false);
    SPField fieldByInternalName = this.GetFieldByInternalName(strName, false);
    if (fieldByInternalName == null)
    {
        fieldByInternalName = this.GetFieldByDisplayName(strName, false);
    }
    if (((fieldByInternalName == null) && (SPContext.Current != null)) && SPContext.Current.IsDesignTime)
    {
        fieldByInternalName = SPContext.Current.ContentType.Fields.GetFieldByInternalName(strName, false);
        if (fieldByInternalName == null)
        {
            fieldByInternalName = SPContext.Current.ContentType.Fields.GetFieldByDisplayName(strName, false);
        }
    }
    if ((fieldByInternalName == null) && bThrowException)
    {
        throw new ArgumentException();
    }
    return fieldByInternalName;
}
Т.е. сначала поле ищется по InternalName, потом по DisplayName, потом внутри контентного типа так же по InternalName ,потом по DisplayName.

среда, 21 апреля 2010 г.

SharePoint: How to get FeatureId for default ListTemplateType

Иногда бывает необходимо получить FeatureId для одного из стандартных типов листов. Например это может быть нужно для использования метода SPListCollection.Add.

Для этого можно использовать internal тип Microsoft.SharePoint.LegacyListTemplate

Вот примерчик:
var LegacyListTemplateType = typeof(SPSite).Assembly.GetType("Microsoft.SharePoint.LegacyListTemplate");
var method = LegacyListTemplateType.GetMethod("LookupAssociatedFeatureId");
var FeaureId =  method .Invoke(null, new object[] { SPListTemplateType.GenericList }) as string;             

SharePoint 2010: How to upload big files use client object model

Можно делать вот так:

using (var clientContext = new ClientContext("http://myserver"))
{
    using (FileStream fs = new FileStream(@"C:\myfile.doc", FileMode.Open))
    {
         File.SaveBinaryDirect(clientContext, "ce/SuperDocLib/myfile.doc", fs, false);
    }
}


Нашел тут.

вторник, 20 апреля 2010 г.

SharePoint: Built in fields

Оказывается есть стандартный тип SPBuiltInFieldId , в котором перечислены все идентификаторы всех стандартных полей. Это очень удобно т.к. отпадает необходимость писать код вида:

var list = web.Lists["MySuperList"];
var email = list.Items[0]["EmailFrom"];

и беспокоится что поле могло быть переименовано.

Можно писать так:

var list = web.Lists["MySuperList"];
var email = list.Items[0][SPBuiltInFieldId.EmailFrom];

вторник, 13 апреля 2010 г.

Log4net: How to log messges to different log files

Для логгирования в шарповом проекте пользуюсь log4net , и все бы хорошо, но потребовалось, чтобы при обработки разных задании логи каждого задания сохранялись в свой лог ,причем имя задания (а следовательно и имя лога) формируется на runtime ,при этом поток сообщении не относящихся к этим заданиям все так же должен сыпаться в основной лог файл.

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

var log1 = log4net.LogManager.GetLogger("Manage");
var log2 = log4net.LogManager.GetLogger("Requests");
var log3 = log4net.LogManager.GetLogger("Task");
var log4 = log4net.LogManager.GetLogger("Results");

Все логи кроме "Task" должны складываться в файл "all.log" ,а лог "Tasks" в файлы вида "task_.log".

Для того чтобы это работало нам нужно разделить поток сообщении от всех логгеров на два appender'а. Сделать это можно с помощью стандартных фильтров:

  
    
      
       ...
 
  
  
  
    
    
      
        ...
 
  
  
  
 
    
     
       
       
       
     

Т.е. в appender "all" мы пишем все кроме того что отправлено через логгер "tasks" ,а в appender "tasks" только то что через "tasks" и больше ничего (DenyAllFilter).

Но нам то еще надо чтобы имя лога менялось!

Для этого сделаем вот такой код по переключению:
var hierarchy = (Hierarchy)log4net.LogManager.GetRepository();
var rol = (RollingFileAppender)hierarchy.Root.GetAppender("task");
rol.File = Path.GetDirectoryName(rol.File)+string.Format(@"\task_{0}.log",taskname);
rol.ActivateOptions();

четверг, 8 апреля 2010 г.

Specify how long entries are kept in change log use SharePoint Object Model

Этот лог нужен для того чтобы иметь возможность получать изменения происходившие в SharePoint в определенный период. По умолчанию там храняться данные лишь за последние 15 дней.

Само свойство "описано" тут

Выставить его можно вот так:
var site = new SPSite("http://server");
site.WebApplication.ChangeLogRetentionPeriod = new TimeSpan(50,0,0,0);
site.WebApplication.ChangeLogExpirationEnabled = true;
site.WebApplication.Update();

В Central Administration от настраивается в "Application Management > Web Application General Settings > Change Log"

среда, 7 апреля 2010 г.

SharePoint 2010: Client Object Model API

Дошли руки посмотреть Client Object Model API появившийся в SharePoint 2010

API внешне практически полностью повторяет Server Object Model API, который был в SharePoint 2007.

Немного необычно выглядит необходимость использования методов Load и ExecuteQuery, а так же повсеместное внедрение LINQ.

Пример кода выводящего имена подсаитов корневой сайтовой коллекции:

var clientContext = new ClientContext("http://remotesrv14");
var site = clientContext.Web;

var webs = site.Webs;
clientContext.Load(webs);
clientContext.ExecuteQuery();
foreach (var web in webs)
    Console.WriteLine(web.Title);
clientContext.ExecuteQuery();

Порадовало что не запрещается менять пользователя и время создания для элементов листов:

var lst = site.Lists.GetByTitle("Test lst");
var itemCreateInfo = new ListItemCreationInformation();
ListItem listItem = lst.AddItem(itemCreateInfo);
listItem["Title"] = "Write specs for user interface."+DateTime.Now.ToShortTimeString();
listItem["Category"] = "Specification";
listItem["Author"] = 66;
listItem["Editor"] = 67;

listItem["Created"] = DateTime.Now.AddYears(-10);
listItem["Modified"] = DateTime.Now.AddYears(-5);

listItem.Update();

clientContext.ExecuteQuery();

А вот разочаровало, что через Client Object Model API, создавать и удалять сайтовые коллекции - нельзя. Очень надеюсь что останется хотя бы метод в CreateSite в Admin Web Services.

воскресенье, 4 апреля 2010 г.

Far Manager v2.0

За последние пару лет мой любимый файловый менеджер\редактор\IDE и практически оболочка для Windows - FAR стал интенсивно разрабатываться и добавлять приятные мелочи.
Поставил на свои машины 2.0.1420 ,вместо альфы двух летней давности - пока доволен. Надо будет проверить как он вертится под Win2k3 x64\x86, раньше у меня были вылеты на ней.

Молодцы ребята,не дают загнуться инструменту моей молодости ;) ,которым я пользуюсь уже больше 10 лет.

А до этого был DOS Navigator'а ,ну да это уже совсем давно было. :)

Mercurial+DropBox: Локальный репозитории с синхронизацией

Приходится работать за разными машинами и я начал хранить часть своих, небольшх, проектов в папке DropBox, но столкнулся с тем что мне не хватает традиционных для систем source control'а возможностей по сохранению версии и брэнчиванию. При этом я не хочу отказываться от возможности локальной работы на любой из своих машин.
Решение вопроса оказалось очень простым - создать в папке DropBox ,локальный репозитории Mercurial.
При этом на всех машинах я имею идентичный репозитории, могу создавать бренчи и контролировать версии абсолютно не завися от того на какой из своих машин я работаю.

пятница, 2 апреля 2010 г.

Fun: Diagrams

Вот так вот работает наш продукт :)


Python: Get dll version

Так можно получить информацию о версии из dll

from win32api import GetFileVersionInfo, LOWORD, HIWORD

def get_version_number (filename):
 info = GetFileVersionInfo (filename, "\\")
 ms = info['FileVersionMS']
 ls = info['FileVersionLS']
 return HIWORD (ms), LOWORD (ms), HIWORD (ls), LOWORD (ls)

if __name__ == '__main__':
 import os
 a,b,c,d = get_version_number (r'..\mySuperProgram.exe')
 print "%d.%d.%d.%d"%(a,b,c,d)

Нашел тут