Showing posts with label Blogger. Show all posts
Showing posts with label Blogger. Show all posts

Friday, July 16, 2010

PRE Tag Internet Explorer Scrollbar Solution

<pre> tag is very useful for writing code. I use it all the time actually for posting C# code.
There is however a problem with Internet Explorer:
If the text is too long, and a horizontal scroll bar appears, it overlaps the bottom line.
You can find many solutions to this problem in this link, including scanning the document with JavaScript fixing all the pre tags.
My solution is a lot simpler.

Solution:
If you know that the text is too long and a horizontal scroll bar will appear, then add the following code at the bottom, just before the </pre> ending tag:

<!--[if IE]>

<![endif]-->

Explanation:
If the user is using Internet Explorer, then there will be an extra (empty) line inside the pre tag, and the horizontal scroll bar will overlap the empty line and not the original content.

Monday, June 28, 2010

Blogger C# API

Source: http://google-gdata.googlecode.com/svn/trunk/clients/cs/samples/blogger/ConsoleSample.cs

using System;
using System.Text;
using Google.GData.Client;
using System.Net;
using System.Xml;
using System.Text.RegularExpressions;

namespace BloggerDevSample
{
    class ConsoleSample
    {
        /** Lists the user's blogs. */
        static void ListUserBlogs(Service service)
        {
            Console.WriteLine("\nRetrieving a list of blogs");
            FeedQuery query = new FeedQuery();
            // Retrieving a list of blogs
            query.Uri = new Uri("http://www.blogger.com/feeds/default/blogs");
            AtomFeed feed = null;
            feed = service.Query(query);
            foreach (AtomEntry entry in feed.Entries)
            {
                Console.WriteLine("  Blog title: " + entry.Title.Text);
            }
        }

        /** Lists the user's blogs and returns the URI for posting new entries
         * to the blog which the user selected.
         */
        static Uri SelectUserBlog(Service service)
        {
            Console.WriteLine("\nPlease select a blog on which to post.");
            FeedQuery query = new FeedQuery();
            // Retrieving a list of blogs
            query.Uri = new Uri("http://www.blogger.com/feeds/default/blogs");
            AtomFeed feed = service.Query(query);

            // Publishing a blog post
            Uri blogPostUri = null;
            if (feed != null)
            {
                foreach (AtomEntry entry in feed.Entries)
                {
                    // Print out the title of the Blog
                    Console.WriteLine("  Blog name: " + entry.Title.Text);
                    Console.Write("  Post to this blog? (y/n): ");
                    if (Console.ReadLine().Equals("y"))
                    {
                        // find the href in the link with a rel pointing to the blog's feed
                        for (int i = 0; i < entry.Links.Count; i++)
                        {
                            if (entry.Links[i].Rel.Equals("http://schemas.google.com/g/2005#post"))
                            {
                                blogPostUri = new Uri(entry.Links[i].HRef.ToString());
                                Console.WriteLine("  Your new posts will be sent to " + blogPostUri.AbsoluteUri.ToString());
                            }
                        }
                        return blogPostUri;
                    }
                }
            }
            return blogPostUri;
        }

        /** Creates a new blog entry and sends it to the specified Uri */
        static AtomEntry PostNewEntry(Service service, Uri blogPostUri)
        {
            Console.WriteLine("\nPublishing a blog post");
            AtomEntry createdEntry = null;
            if (blogPostUri != null)
            {
                // construct the new entry
                AtomEntry newPost = new AtomEntry();
                newPost.Title.Text = "Marriage!";
                newPost.Content = new AtomContent();
                newPost.Content.Content = "
" + "

Mr. Darcy has proposed marriage to me!

" + "

He is the last man on earth I would ever desire to marry.

" + "

Whatever shall I do?

" + "
"; newPost.Content.Type = "xhtml"; newPost.Authors.Add(new AtomPerson()); newPost.Authors[0].Name = "Elizabeth Bennet"; newPost.Authors[0].Email = "liz@gmail.com"; createdEntry = service.Insert(blogPostUri, newPost); if (createdEntry != null) { Console.WriteLine(" New blog post created with title: " + createdEntry.Title.Text); } } return createdEntry; } /** Creates a new blog entry and sends it to the specified Uri */ static void PostAndDeleteNewDraftEntry(Service service, Uri blogPostUri) { Console.WriteLine("\nCreating a draft blog post"); AtomEntry draftEntry = null; if (blogPostUri != null) { // construct the new entry AtomEntry newPost = new AtomEntry(); newPost.Title.Text = "Marriage! (Draft)"; newPost.Content = new AtomContent(); newPost.Content.Content = "
" + "

Mr. Darcy has proposed marriage to me!

" + "

He is the last man on earth I would ever desire to marry.

" + "

Whatever shall I do?

" + "
"; newPost.Content.Type = "xhtml"; newPost.Authors.Add(new AtomPerson()); newPost.Authors[0].Name = "Elizabeth Bennet"; newPost.Authors[0].Email = "liz@gmail.com"; newPost.IsDraft = true; draftEntry = service.Insert(blogPostUri, newPost); if (draftEntry != null) { Console.WriteLine(" New draft post created with title: " + draftEntry.Title.Text); // Delete the newly created draft entry Console.WriteLine(" Press enter to delete the draft blog post"); Console.ReadLine(); draftEntry.Delete(); } } } /** Display the titles for all entries in the previously selected blog. */ static void ListBlogEntries(Service service, Uri blogUri) { if (blogUri != null) { Console.WriteLine("\nRetrieving all blog posts"); // Retrieve all posts in a blog FeedQuery query = new FeedQuery(); Console.WriteLine(" Query URI: " + blogUri.ToString()); query.Uri = blogUri; AtomFeed feed = service.Query(query); foreach (AtomEntry entry in feed.Entries) { Console.WriteLine(" Entry Title: " + entry.Title.Text); } } } /** Display title for entries in the blog in the hard coded date range. */ static void ListBlogEntriesInDateRange(Service service, Uri blogUri) { Console.WriteLine("\nRetrieving posts using query parameters"); // Retrieve all posts in a blog between Jan 1, 2006 and Apr 12, 2007 FeedQuery query = new FeedQuery(); query.Uri = blogUri; query.MinPublication = new DateTime(2006, 1, 1); query.MaxPublication = new DateTime(2007, 4, 12); AtomFeed feed = service.Query(query); foreach (AtomEntry entry in feed.Entries) { Console.WriteLine(" Entry Title: " + entry.Title.Text); } } /** Change the contents of the newly created blog entry. */ static AtomEntry EditEntry(AtomEntry toEdit) { Console.WriteLine("\nUpdating post"); // Edit the new entry if (toEdit != null) { toEdit.Title.Text = "Marriage Woes!"; Console.WriteLine(" Press enter to update"); Console.ReadLine(); toEdit = toEdit.Update(); } return toEdit; } /** Delete the specified blog entry. */ static void DeleteEntry(AtomEntry toDelete) { Console.WriteLine("\nDeleting post"); // Delete the edited entry if (toDelete != null) { Console.WriteLine(" Press enter to delete the new blog post"); Console.ReadLine(); toDelete.Delete(); } } /** Get the comments feed URI for the desired blog entry. */ static Uri SelectBlogEntry(Service service, Uri blogPostUri) { Console.WriteLine("\nPlease select a blog entry on which to comment."); FeedQuery query = new FeedQuery(); query.Uri = blogPostUri; AtomFeed feed = service.Query(query); Uri commentPostUri = null; if (feed != null) { foreach (AtomEntry entry in feed.Entries) { // Print out the title of the Blog Console.WriteLine(" Blog entry title: " + entry.Title.Text); Console.Write(" Post a comment on this entry? (y/n): "); if (Console.ReadLine().Equals("y")) { // Create the Post URL for adding a comment by finding this entry's id number. // Find the href in the link with a rel pointing to the blog's feed. for (int i = 0; i < entry.Links.Count; i++) { if (entry.Links[i].Rel == "edit") { string commentUriStart = Regex.Replace(blogPostUri.ToString(), "/posts/default", ""); string selfLink = entry.Links[i].HRef.ToString(); string entryId = Regex.Replace(selfLink, blogPostUri.ToString() + "/", ""); // Build the comment URI from the blog id in and the entry id. commentPostUri = new Uri(commentUriStart + "/" + entryId + "/comments/default"); Console.WriteLine(" Your new comments will be sent to " + commentPostUri.ToString()); return commentPostUri; } } } } } return commentPostUri; } static AtomEntry PostNewComment(Service service, Uri commentPostUri) { Console.WriteLine("\nCommenting on a blog post"); AtomEntry postedComment = null; if (commentPostUri != null) { // Add a comment. AtomEntry comment; comment = new AtomEntry(); comment.Title.Text = "This is my first comment"; comment.Content.Content = "This is my first comment"; comment.Authors.Add(new AtomPerson()); comment.Authors[0].Name = "Blog Author Name"; postedComment = service.Insert(commentPostUri, comment); Console.WriteLine(" Result's title: " + postedComment.Title.Text); } return postedComment; } static void ListEntryComments(Service service, Uri commentUri) { if (commentUri != null) { Console.WriteLine("\nRetrieving all blog post comments"); // Retrieve all comments on a blog entry FeedQuery query = new FeedQuery(); Console.WriteLine(" Query URI: " + commentUri.ToString()); query.Uri = commentUri; AtomFeed feed = service.Query(query); foreach (AtomEntry entry in feed.Entries) { Console.WriteLine(" Comment Title: " + entry.Title.Text); } } } static void DeleteComment(AtomEntry commentEntry) { Console.WriteLine("\nDeleting the comment"); if (commentEntry != null) { // Delete the comment. Console.WriteLine(" Press enter to delete the new comment post"); Console.ReadLine(); commentEntry.Delete(); } } static void Main(string[] args) { Service service = new Service("blogger", "blogger-example"); // ClientLogin using username/password authentication string username; string password; if (args.Length != 2) { Console.WriteLine("Usage: BloggerDevSample.exe <username> <password>"); return; } else { username = args[0]; password = args[1]; } service.Credentials = new GDataCredentials(username, password); ListUserBlogs(service); Uri blogPostUri = SelectUserBlog(service); AtomEntry createdEntry = PostNewEntry(service, blogPostUri); PostAndDeleteNewDraftEntry(service, blogPostUri); ListBlogEntries(service, blogPostUri); ListBlogEntriesInDateRange(service, blogPostUri); AtomEntry editedEntry = EditEntry(createdEntry); DeleteEntry(editedEntry); Uri commentPostUri = SelectBlogEntry(service, blogPostUri); AtomEntry commentEntry = PostNewComment(service, commentPostUri); ListEntryComments(service, commentPostUri); DeleteComment(commentEntry); Console.WriteLine("Press enter to quit"); Console.ReadLine(); } } }

Saturday, June 19, 2010

Google Command Line

Project homepage:
http://code.google.com/p/googlecl/

It is originally for *nix, but can also be used on Windows:
http://publicint.blogspot.com/2010/06/setup-googlecl-on-winxp.html

From the usage examples:

Blogger
  • google blogger post --tags "GoogleCL, awesome" --title "Test Post" "I'm posting from the command line"
  • google blogger post blogpost.txt
  • google blogger list title,url-site # List posts
  • google blogger delete --title "Test Post"
  • google delete --title "Silly post number [0-9]*" # Delete posts matching regex
  • google tag --title "Dev post" --tags "Python, software" # label an existing post

Calendar

  • google calendar add "Dinner party with George today at 6pm" # add event to calendar
  • google calendar today # List events for today only.
  • google calendar list --date 2010-06-01,2010-06-30 # List events.
  • google calendar delete --title "Dinner party with George" # Delete an event.

Contacts

  • google contacts add "J. Random Hacker, jrandom@example.com"
  • google contacts list name,email --title "J. Random Hacker"
  • google contacts delete --title "J. Random Hacker"

Docs

  • google docs delete --title "Evidence"
  • google docs edit --title "Shopping list" --editor vim
  • google docs get --title "Homework [0-9]*"
  • google docs list title,url-direct --delimiter ": " # list docs
  • google docs upload the_bobs.csv ~/work/docs_to_share/*

Picasa

  • google picasa create --title "Vermont Test" --tags Vermont vermont.jpg
  • google picasa get --title "Vermont Test" /path/to/download/folder
  • google picasa list title,url-direct --query "A tag"
  • google picasa post --title "Vermont Test" ~/old_photos/*.jpg # Add to an album
  • google picasa tag --title "Vermont Test" --tags "places"
  • google picasa delete --title "Vermont Test" # delete entire album

Youtube

  • google youtube post --category Education --devtags GoogleCL killer_robots.avi
  • google youtube delete --title "killer_robots.avi"
  • google youtube list # list my videos
  • google youtube tag -n ".*robot.*" --tags robot

Search, Buzz, Gmail, etc.

Monday, June 7, 2010

Get IMDB movie rating using JavaScript (Cross domain AJAX solution)

UPDATE: I modified my script to use imdbparser.appspot.com that I built, so the information is always accurate and it works fast.
This query:
https://imdbparser.appspot.com/?callback=foo&context=bar&action=rating&id=tt0411008
Gives this result: foo('bar', '8.7')
So you can write something like that:

<script type="text/javascript">
function foo(context, rating)
{
  alert("The rating is: " + rating);
}
</script>
<script src="https://imdbparser.appspot.com/?callback=foo&context=bar&action=rating&id=tt0411008" type="text/javascript">
</script>

Original Post:



Solution to what exactly?

In JavaScript you aren't suppose to communicate with other sites, such as IMDB. As a result, you can't get the rating of a movie just like that.
For more information:
http://en.wikipedia.org/wiki/Same_origin_policy

Example: Vicky Cristina Barcelona

How to use it in your website?

Put this code in the top of the page:
<script src="http://sites.google.com/site/ycouriel/files/imdbrating.js" type="text/javascript"> </script>
Put this code each time you want to get rating:
<script type="text/javascript"> IMDBRATING.registerTitle("tt0068646");</script>
Finally, put this code in the bottom of the page: 
<script type="text/javascript"> IMDBRATING.processTitles();</script>
You also need to put this CSS if you want the nice stars: imdbrating.css


How it's done?

The trick is to use Google. Consider the following query:
You get in return:
IMDBRATING.ratingCallback( <search results here> );
This wonderful feature of Google allows you to write a query as the source of JavaScript: 
<script src=" <the query above here> " type="text/javascript"> </script>
By parsing the search results, you can easily find the rating.

Notes:
  • This is a JavaScript solution; if you have a server running PHP or something you can put some page like Google's, only instead of search results you return the ratings. This could be wonderful, but all the websites on the Internet that do exactly that didn't work for me or were very slow.
  • The rating you get is sometimes not updated, it entirely depends on how often Google database is updated.

Sunday, February 21, 2010

Add C# Code Formatter Widget To Your Blog

This widget formats all the C# code in your blog so it looks exactly like in Visual Studio.
It supports all the cases of string literals, comments, keywords and preprocessors. It has a huge list of all commonly used types, and it has some capability of learning new types (classes, enums, interfaces, structs) from your code.
Try it now online! - OR - Add it to your blog:
Note: the widget is for lazy people like me, if you want you can add the formatting script to your HTML Layout manually.

Here is a simple example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace exp1
{
    class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello, world!");
        }
    }
}

This is what the author sees when writing the post:
<pre formatcs="1">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace exp1
{
    class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello, world!");
        }
    }
}</pre>

So how does it work?
The script scans the page looking for <pre> elements with the attribute formatcs=1. Each element is then formatted as C# code.
The <pre> tag was chosen for a reason - if the user doesn't have JavaScript supported, then the <pre> tag is the best way to show code in a blog.

Here is a more advanced example:
[XmlRoot("Node")]
class MyNode<T> : MyBaseClass<T>
    where T : Dictionary<List<T>, int>, ISerializable
{
    MyNode MyNode = new SuperNode();
    
    /// <summary>   *
    /// comment2... *
    /// </summary>  *
    MyType1 foo(out MyType2 x)
    {
        x = MyType1.StaticFunction(@"c:\");
        Console.WriteLine(" aaaa \" \\\" \\\\");
        return new T();
    }
}
Note that these classes are being deduced by reading the code: MyNode, MyBaseClass, SuperNode, MyType1, MyType2.
Note that "T" is not styled as a type, exactly as in Visual Studio.

OK OK! I'm convinced! How do I add this widget to my blog?
Simply by clicking here:
- Or - You can use the online version here:
formatmycsharpcode.blogspot.com

For more information refer to this wiki page.

Thursday, February 18, 2010

How to add a new Blogger post with labels from C#

First download and install Google API from here:
http://code.google.com/p/google-gdata/downloads/list

Add a reference to "Google Data API Core Library",
and use the following function:


public static bool AddPost(string title, string bodyHTML, string[] labels)
{
    Service service = new Service("blogger", "<program name>");
    service.Credentials = new GDataCredentials("<username>", "<password>");
    AtomEntry newPost = new AtomEntry();
    newPost.Title.Text = title;
    newPost.Content = new AtomContent();
    newPost.Content.Content = bodyHTML;
    newPost.Content.Type = "html";
    foreach (string label in labels)
    {
        AtomCategory cat = new AtomCategory();
        cat.Scheme = new Uri("http://www.blogger.com/atom/ns#");
        cat.Term = label;
        newPost.Categories.Add(cat);
    }
    AtomEntry response = null;
    try
    {
        response = service.Insert(new Uri("<uri>"), newPost);
    }
    catch (GDataRequestException exception)
    {
        if (exception.ResponseString == "Blog has exceeded rate limit or otherwise requires word verification for new posts")
        {
            return false;
        }
        else
        {
            throw exception;
        }
    }
    if (response == null)
    {
        throw new Exception("Something went wrong");
    }
    return true;
}

Note what you need to replace:
Also note the marked yellow line. It took me some nasty googling time to find it. You must put it for the labels to work.

Blogger like search box

I copied the Blogger search box and added the following features:
  • It shows the current search keywords after you invoked the search (by parsing the URL)
  • It has a border that becomes gray when mouse is on the box
  • It has a faded string when not in focus, and it disappears when in focus
Take a look:
http://ycouriel-archive.blogspot.com/
(It's on the sidebar)

This is actually the first time I'm using HTML, JavaScript and CSS.
So I hope the code won't be that embarrassing:

<div id="b-navbar2">
<form style="display: inline;" method="get" action="http://ycouriel-archive.blogspot.com/search" id="searchthis">
<div id="b-query-box" style="width: 193.7px;" >
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<style type="text/css">
#b-navbar2{
white-space:nowrap;color:#fff;height:29px;border-bottom:1px solid #024;background:transparent;font-size:13px;font-family:Arial,Sans-serif
}
#b-navbar2 #b-query-box{
background-color:#fff;margin:0 .5em 0 0;border:1px solid transparent;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;padding:0 .3em
}
#b-navbar2 #b-query-box:hover{
border:1px solid #999999;
}
#b-navbar2 #b-query-icon{
display:block;width:13px;height:13px;cursor:pointer;cursor:hand;background:url(http://img1.blogblog.com/img/navbar/icons_orange.png) no-repeat 0 0
}
#b-navbar2 #b-query-icon:hover{
background:url(http://img1.blogblog.com/img/navbar/icons_orange.png) no-repeat -13px 0
}
#b-navbar2 #b-query{
font-size:13px;color:#000;background-color:transparent;border:none;margin:0
}
</style>
<td valign="middle">
<input type="text" title="Search" style="width: 180px; color: #999999;" tabindex="3" name="q" id="b-query" onblur="if (this.value == '') {this.value = 'Search...'; this.style.color='#999999';}" onfocus="if(this.value == 'Search...') {this.style.color='#000000';this.value = '';}" value="Search...">
</td>
<td valign="right" style="width: 15px;">
<a title="Search this blog" onclick="document.getElementById(&quot;searchthis&quot;).submit();" id="b-query-icon"></a></td></tr></tbody></table></div></form>
<script language="JavaScript">
function gup( name )
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return results[1];
}

function decode(encoded) {
    return decodeURIComponent(encoded.replace(/\+/g, " "));
}

var q = gup("q");
if (q != "") {
    var lmnt = document.getElementById("b-query");
    lmnt.value = decode(q);
    lmnt.style.color = "#000000";
}
</script>

Thursday, October 22, 2009

Copy code with syntax highlights - Visual Studio and Notepad++

To copy from Visual Studio, first paste in Word, then copy from Word and paste in target

To copy from Notepad++, use the NppExport plugin
(I found the solution here)
Select your code, then: Plugins -> NppExport -> Copy all formats to clipboard
To create a shortcut for this command, you can use Settings -> Shortcut mapper...
I use Ctrl+Shift+C for this command

Update: See a better solution for C# here