Thursday, January 09, 2014

SPCoder


I've been developing code for MS SharePoint since year 2004. SharePoint was evolving with every new version since then, but all the versions had one thing in common and that is the lack of an "easy" way to manipulate its object model. By "easy" here I mean visual, fast, scriptable. There is no tool where developer/admin could write some code in a visual environment directly on server, using full SharePoint object model, execute it, share it, etc.

There are a lot of very useful blogs out there where SP developers share a solution to a problem solved by writing simple console application which usually has 5-10 lines of code in which they call a couple of methods from SP object model. I also wrote a number of console apps like that in different situations and it was always taking me a lot of time.. firing up a dev machine with visual studio, writing code/compiling/testing on dev machine, publishing app to server and executing. Of course if you have to change anything you have to go through the procedure of write/compile/test/publish/execute again...

Ok, you certainly get my point by now :) So, my solution to this problem was to write a tool which you can use to interactively work with SharePoint's object model. It is called SPCoder, it is free to use and you can download it from https://spcoder.codeplex.com.

About

SPCoder uses IronPython for accessing SharePoint's object model. It works on server and foundation versions of SharePoint 2007, 2010 and 2013. Here is the screenshot of SPCoder in action:


You don't have to have any previous knowledge of IronPython in order to use SPCoder. In fact SPCoder has very useful features which you can use without any coding (Describer and Property viewer). The documentation of all the SPCoder's features can be found here: https://spcoder.codeplex.com/documentation
 
Here are a couple examples on what can be done with SPCoder:

#download all files from the SP library to a local folder
local = "C:\Temp\Imgs"
for i in list.Items:
    f = i.File    
    binary = f.OpenBinary()    
    stream = IO.FileStream(local + "/" + f.Name, IO.FileMode.Create)
    writer = IO.BinaryWriter(stream)
    writer.Write(binary)
    writer.Close()
 --

#add users to a security group if usernames are located in the SP list 
gr = web.SiteGroups["group_name"]
for l in list1.Items:
    u = web.EnsureUser(l["UserId"])
    gr.AddUser(u)
--

#change the content type for all items in the list
ct = list2.ContentTypes["ct_name"]
for i in list2.Items:  
    i["Content Type"] = ct.Name;
    i["Content Type ID"] = ct.Id.ToString();
    i.SystemUpdate()
--

The important thing to note here is that these example scripts will work on any SP server, you just need to drag'n'drop appropriate objects to SPCoder context window and name them like web, list, list1 and list2 (which SPCoder does by default for these types of objects).

If you want to try SPCoder, please first take a look at this Quick Tutorial. It will take you just a few minutes but it will give you all you need for start.

Monday, July 30, 2007

Dynamic generation of javascript code

One of the biggest problems for every developer/software architect is the level of generalization/specialization of their code.
If the code is more coupled to the problem , it solves the problem better, but when the problem changes it is harder to change the code. And the oposite .. when the code is more abstract it is easier to change it, but then (generally speaking) the solution is not so good (as it could be in first case).

I am not going to write about the right level of abstraction, because I don’t know it :)
Instead, I am going to write about javascript and some of its interesting features.

Assume that we have the following problem:
We need to write a function that calculates the sum of first n integers.
The first solution that would probably come to everyone’s mind would be the classic for loop that loops from 1 to n and adds value of the counter to some variable..
It could be written as:

function getSum1(n)
{
var s = 0;
for(var i = 1; i <= n; i++)
s += i;
return s;
}


This is, of course, totally correct solution, but is it the best one?
Well, it solves the problem.. and is flexible enough to calculate the sum for every given integer.. so, it probably is the best.
But!
What if we know the number that will be passed to the function before it is called?
If so, it would be better if we wrote the function like this:

function getSum2()
{
return 1+2+3+4+5+6+7+8+9+10;
}

It would be much faster than the first one.
But, as the beginning of this post says.. it is not flexible. It solves the problem, but it is very coupled to it, so when the problem changes (the number n) it is useless.
We have 2 solutions. Which is better? Well, it depends on the fact how many times is function going to be called with the same parameter, and the importance of the execution speed.

I wrote some tests that can be found here.
There are functions that calculate sum of the first 100 integers, and are called 100000 times.

First one calls the function with the classic for loop (getSum1):

var howManyTimes = 100000;
timeStart = new Date();
for (var i = 0; i<howManyTimes; i++)
{
result = getSum1(100);
}
timeStop = new Date();

It then prints duration and the result.

The second test calls the function that generates the code for getSum2 function. After generating , the code is evaluated using the eval function (so the new function is created dynamically):

function createFunction1(val,functName)
{
var code = "function "+functName+"\n{ \n return 0";
for (var i=1; i<=val;i++)
code+="+"+i;
code += "; \n }";
return code;
}

timeStart = new Date();
var code = createFunction1(100,"getSum2()");
eval(code);

for (var i = 0; i<howManyTimes; i++)
{
result = getSum2();
}
timeStop = new Date();

After that it also prints duration and the result.
And finally the third test generates the function using javascript Function object.

function createFunction2(val)
{
var code = " return 0";
for (var i=1; i<=val;i++)
code+="+"+i;
code += ";";
return code;
}

timeStart = new Date();
var code = createFunction2(100);
var getSum3 = new Function(code);

for (var i = 0; i<howManyTimes; i++)
{
result = getSum3();
}
timeStop = new Date();

You can see the results of the tests if you run the test file in your browser.
My average results are:

In firefox: getSum1 ~ 4900ms
getSum2 ~ 550ms
getSum3 ~ 450ms
In IE6: getSum1 ~ 4800ms
getSum2 ~ 840ms
getSum3 ~ 740ms


After all this you can say… ok, this is fine, but.. is there any chance that we can use this in real world, in something more complex than the sum of n numbers?
Well, there might be.
Some of today’s most popular java and .NET frameworks (Spring, Spring.NET) use dynamic code generation in their AOP libraries.

I think that in near future some applications could have "smart execution controllers" that would know whether to call an abstract code or to generate concrete code and call it. Especially in applications where performance (speed) is bottle neck.

Friday, July 27, 2007

Trick Google Calendar and send free SMS!

You have probably heard about google calendar's option for sending free SMS notifications about your calendar events.
Some time ago, while playing with google-calendar-data-api , I got an idea to write a program that would allow its users to send sms for free.
Sender and recipient both must have their google calendar account.
Recipient MUST set up her/his account for receiving SMS messages(This can be done in google calendar in "Settings->Mobile Setup") and then for receiving SMS notifications (in "Settings->Calendars->Notifications" check the "New invitations: SMS" checkbox).

So, how it works..
When a sender wants to send sms, she/he enters the text of the message and email address(es) of the recipient(s). Then the program, using google-calendar-data-api, tricks google calendar by creating an event (with no body, just the subject (text of the message)) and invites recipient(s) to that event (by sending the event notification to all email addresses user entered).

After that, the google calendar account of every recipient informs her/him about the event she/he is invited to by sending the sms notification which contains the event's subject.

And that is it.
Google Calendar becomes the free sms service :)

Of course there are some limitations.
Anyone can receive up to 20 messages per day, up to 150 per month. (Number of messages the user can send is unlimited)
The format of the message is: "SENDER'S NAME invites you to: MESSAGE TEXT @time and date"
The sms is sent by google, so my program can't do anything to format it.
The number of the characters for MESSAGE TEXT depends on the length of sender's name.
There are about 60 characters available in my case.
If your text contains more than that number, the program will split the text and create as much the events as necessary and send several sms messages.

The program (written in java) can be downloaded from here

note:
You can't send sms to yourself.

Friday, February 16, 2007

alat:firebug - žrtva: google calendar

Kada sam pre nekog vremena napisao programčić za besplatno slanje SMS poruka korišćenjem Google Calendar-ovog servisa za SMS notifikacije, mnogim ljudima se svidela ideja i hteli su da probaju kako radi program, ali kada su se ulogovali na svoj Google Calendar i pokušali da ga podese dočekalo ih je neprijatno iznenađenje. Srbije nije bilo u spisku podržanih zemalja.
U razgovoru sa Ivanom i još nekim ljudima zaključio sam da, verovatno zbog skorašnjeg raskida Srbije i Crne Gore ekipa koja održava Google Calendar baš tih dana razdvaja i podatke o zemljama iz bivše zajednice. Međutim, izgleda da im mnogo treba za jednu tako prostu operaciju :)

U međuvremenu sam, igravši se sa Firebug extenzijom za Firefox, došao na ideju da probam da prevarim GCalendar, da iako Srbije nema na spisku pokušam da je na silu ubacim i registrujem broj za slanje SMS poruka. Kolega sa posla mi je pomogao, ustupivši mi svoj nalog na kome nije imao registrovane SMS notifikacije.
Uspeli smo iz prve :)
Pokazalo se da i svemoćni google ponekad nešto zaboravi, tj. da su promenili podatke na serveru, ali da nisu update-ovali korisnički interface.

Za one koji žele da urade istu stvar sledi malo uputstvo:
  1. Instalirajte Firefox (ukoliko ga imate pređite na sledeći korak)
  2. Instalirajte Firebug add-on za Firefox
  3. Ulogujte se na svoj Google calendar i otvorite Settings->Notifications
  4. Aktivirajte firebug.
  5. U firebug-u kliknite na dugme Inspect i potom na listu zemalja koja se nalazi na otvorenoj Notifications stranici
    Time u firebug-u dobijate označen HTML kod tačne lokacije te liste (HTML select tag)
  6. U firebug-u u select tag-u pronađite bilo koju zemlju (npr. Andorra , ona je među prvima na spisku) i izmenite polje value. Umesto AD (Andorra) stavite RS (Republika Srbija) i pritisnite Enter.
    Time ste završili sa firebug-om.
  7. Sada u spisku zemalja na stranici odaberite Andoru, u polje za unos broja telefona unesite svoj broj telefona (+3816...) i kliknite na dugme Send verification code.
  8. Kada vam na telefon stigne SMS sa kodom ukucajte ga u polje Verification code i kliknite Finish setup.
Time je vaše hakovanje uspelo :)
Sad možete da koristite Google Calendar-ov servis za slanje SMS poruka.

Ukoliko želite da probate gore pomenuti programčić uputstvo možete naći ovde

Saturday, February 10, 2007

prevodjenje reči sa dva klika

Ukoliko često koristite internet i čitate sajtove na engleskom verovatno vam se dosta puta desi da vam zatreba rečnik. Meni se desi.
Kod mene je do sada situacija bila takva da na brzinu kopiram reč za koju mi treba prevod, otvorim u novom tab-u www.metak.com, paste-ujem reč i sačekam malo dok dobijem prevod.
U principu, i to mi je bilo prihvatljivo jer imam brze prste...
Pre par dana mi je pala na pamet ideja da napravim nešto, uz pomoć čega biste , dok se nalazite na bilo kom sajtu mogli sa dva klika da prevedete željenu reč. Bez otvaranja dodatnih strana i kucanja bilo čega.
I posle malo mučenja to mi je pošlo za rukom.

Napisao sam greasemonkey skriptu koja, kada na bilo kojoj stranici, bilo kog sajta duplo kliknete na neku reč i selektujete je, uzme tu reč, izvrši upit na www.metak.com i prikaže vam rezultat (prevod te reči).
Ova skripta će mnoogo ubrzati moje surfovanje, kao i surfovanje svih ljudi koji je budu koristili.

Uputstvo za instalaciju:
1.Instalirajte Mozilla FireFox (ukoliko ga imate predjite na korak 2)
2.Instalirajte greasemonkey Add-on za Firefox. Možete ga naći na ovoj adresi
3.Instalirajte skriptu za prevodjenje. Skriptu možete naći ovde

I to je to. Na prvoj stranici koju otvorite posle instalacije skripte moći ćete, duplim klikom na bilo koju reč istu i da prevedete sa engleskog na srpski ili srpskog na engleski.

Voleo bih da čujem utiske.
Inače imam još neke idejice u glavi.. pa će uskoro biti još novosti :)

Wednesday, January 24, 2007

cool javascript

Otvorite bilo koji sajt (npr. www.google.com) i u address bar svog browser-a ukucajte
javascript:document.body.contentEditable='true'; document.designMode='on'; void 0
(ili prosto kliknite na ovaj link)

Pošto to uradite moći ćete u browser-u da menjate sadržaj otvorene stranice :)

Na istu foru radi i sledeći script.
Otvorite neku stranicu sa više slika (npr. http://www.b92.net/sport/) i u adress bar ukucajte:
javascript:R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.images; DIL=DI.length; function A(){for(i=0; i-DIL; i++){DIS=DI[ i ].style; DIS.position='absolute'; DIS.left=Math.sin(R*x1+i*x2+x3)*x4+x5; DIS.top=Math.cos(R*y1+i*y2+y3)*y4+y5}R++}setInterval('A()',5); void(0);

(ili link) i posmatrajte sta se desava :D

Sunday, December 24, 2006

Besplatan SMS!

Pre par meseci sam otkrio da google calendar ima opciju za besplatno slanje SMS notifikacija. Može se podesiti da šalje SMS kao podsetnik za događaj iz kalendara ili kao obaveštenje da vas je neko pozvao da prisustvujete nekom događaju.
Ova opcija me je baš obradovala, naročito kad sam video da među zemljama koje su podržane za slanje SMS poruka ima i Srbija.
Nešto posle ovog otkrića sam naleteo na google-calendar-data-api. Pomoću tog API-ja možete napisati aplikaciju za pristupanje google calendar-u. Za igranje sa događajima. Za dodavanje, brisanje, pregled i sl.
Čim sam video na ovaj api, sinula mi je ideja da možda mogu napisati aplikaciju koja će, koristeći isti i gore pomenutu opciju google calendara da služi za besplatno slanje SMSova. I posle malo eksperimentisanja uspeo sam (u nekoj meri) u tome.
Aplikaciju možete preuzeti ovde.
Da biste je mogli koristiti potrebno je da uradite par stvari.
Za slanje poruka potrebno je da imate GMail nalog i kreiran google calendar.
Da biste mogli da primate poruke, potrebno je u podešavanjima google calendar-a da ostavite vaš broj telefona i otkačite opciju za slanje SMS notifikacije za "New invitations".
Što se tiče broja poruka koje mogu da se prime, google ga je ograničio na max 20 dnevno, odnosno 150 mesečno po jednom nalogu. Možete poslati beskonačno mnogo poruka.
Format poruke je malo problematičan, jer ne može iz aplikacije da se utiče na njega. Pošto google šalje poruku ona je oblika: "Damjan Tomic invites you to: TEKST VASE PORUKE @vreme i datum" (ako sa mog naloga nekom šaljem), što znači da ne može svih 160 karaktera da se iskoristi za tekst poruke. Veličina zavisi od duzine imena i prezimena onoga ko šalje poruku. Ja sam stavio da default veličina poruke bude 60 karaktera, ali to svako može promeniti u aplikaciji u zavisnosti od dužine imena i prezimena. Ukoliko je poruka koju želite poslati veća od pomenute dužine, program će je izdeliti na više manjih poruka.
Aplikacija je trenutno u verziji 1.0 :) tako da nema neke od realno potrebnih opcija, kao što su snimanje podešavanja ili spiska kontakata. To će nadam se uskoro biti ubačeno.

Aplikacija je pisana u javi. Potrebno je da imate jre 5.0 na vašem računaru. Ukoliko nemate, možete je skinuti odavde

Source će uskoro biti postavljen na http://gnu.fon.bg.ac.yu/subversion/ pa će svako ko želi moći da se igra sa ovim.

Očekujem komentare sa utiscima i novim predlozima.