Tuesday, 30 August 2016

Sitecore Publishing Restriction Module

All of Sitecore developers know that we can restrict publishing for particular Sitecore item. Now if you set publishing restriction for particular item and try to publish that item with subitems, it will not publish that item but it will publish all subitems as there is NO restrction on subitems.

So there should be an option by which we can restict subitems publishing as well. Below are some examples which made me think about this publishing restriction option.

Sometimes content author or publisher publishes Home item with subitems by mistake
Sometimes  content author or publisher publishes Media Library item with subitems by mistake.

This mistake not only slowed down our stage server but also started publishing all unwanted items.

I have come across this situation many times when my client complains that somebody from content team published Home item with subitems by mistake. This mistake may create disaster for you by publishing all unwanted items on web database which eventually mess up your live website.

So we need to jump to stage server to restart app pool in order to stop publishing. But this solution is not at all accepted.

Moreover, there is no such feature in Sitecore out of the box which can help us to disable publishing for root item with subitems such as "Home" item. This leads me to write an implementation of disabling publish for root items. Then I got an idea - why not write a module which can help our Sitecore community friends who are in the same boat?

Please note that you may have other options but every project has its own existing environment and implemention and sometimes you need to come up with option which can fit into existing implemention.

That's how Sitecore Publishing Restriction Module gets created.
But wait... you may have question  "Have you checked Sitecore MarketPlace before creating this module?"

The answer is - Yes. I have checked and there is a module named "Sitecore Publishing Exclusions" but sadly it doesn't support Sitecore 7 version. Hence I needed to write this module which is supported by Sitecore 6+, 7+ and 8+.

This is a very userful module which will help you to disable or set warning on publishing for all those items which you want to restrict.

As per above configuration whenever you try to publish "Sitecore", "Content" or "Home" item, it will show you warning message. This will eliminate accidently publish without seeing which item is selected.

Moreover, you can completely disable publishing option also for such items. You simply need to uncheck show warning checkbox.

You can also warn your content publisher users about heavy publishing by configuring Heavy Publishing Restriction options. This feature will be very helpful for Sitecore 6+ and 7+ as there is no extra warning message pop-up like in Sitecore 8 publish. Thanks to my collegue Ashish Bansal for giving idea to add this feature.

You can download this module at Sitecore MarketPlace

Once you download and install this module, you need to do a little configuration change suggested below.

Need to comment out existing publish command and add new custom publish command as shown below.

<!--<command name="item:publish" type="Sitecore.Shell.Framework.Commands.PublishItem,Sitecore.Kernel" />-->
  <command name="item:publish" type="Sitecore.SharedSource.CustomPublish,Sitecore.SharedSource"/>

That's it, now you are good to go!

Wednesday, 17 August 2016

How To Track Twitter Emojis Real Time?

In previous post we talked about "How to do live streaming and tracking the tweets?" If you haven't read that post, then I would recommend to Devour it first before moving further.

You will find many articles on internet about live streaming and tracking the tweets, but you will rarely find a way to track twitter emojis real time. There is only one example of tracking twitter emojis real time and it is http://emojitracker.com/

This tracker is awesome and shows live emojis getting used world wide. I have simillar requirement with a small change. My requirement was to track emojis for particular city and show it real time to decide the mood of city.

For example: My client wanted to know the mood of city on internet by tracking emojis on twitter.

Now the link that I shared above (http://emojitracker.com/) was developed on non .NET platform and it was not easy for me to use. Moreover I haven't found any article to track twitter emojis real time using .NET, hence after good amount of research and development I was able to achieve this real time emoji tracking. I am writing this blog post to help my friends who has similar requirement.

It's easy to track tweet based on different criteria such as location and text using TweetInvi API. But the challenge was "How to track emojis?" as it is NOT text. Moreover I needed to store count of these emjois in order to know the mood of cities.

Finally this is how it was achieved.


1) Connect with TweetInvi API and track tweets based on your location (e.g. Dubai in my case)

2) Track twitter emojis by comparing emojis unicode with tweet text. You can a complete list of all           twitter emojis at http://unicode.org/emoji/charts/full-emoji-list.html

3) Store the count of different emojis in database to decide mood of the city.

Finally we created a nice dashboard page which will show LIVE mood of the city. You can also check mood of the city at particular time by changing filter criteria.

Here is the complete code set of above steps.

 class Program
        static SqlConnection con;
        static SqlCommand cmd;
        static void Main(string[] args)
            Auth.SetUserCredentials("key1", "key2", "key3", "key4");

            con = new SqlConnection(ConfigurationManager.ConnectionStrings["sqlCon"].ConnectionString);
            if (con.State != ConnectionState.Open)
            using (var webClient = new WebClient())
                webClient.Proxy = WebRequest.DefaultWebProxy;
                webClient.Credentials = System.Net.CredentialCache.DefaultCredentials; ;
                webClient.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
                webClient.Headers["User-Agent"] = "MOZILLA/5.0 (WINDOWS NT 6.1; WOW64) APPLEWEBKIT/537.1 (KHTML, LIKE GECKO) CHROME/21.0.1180.75 SAFARI/537.1";

                var creds = new TwitterCredentials("key1", "key2", "key3", "key4");

                var stream = Stream.CreateFilteredStream();
                var dubaiCords = new Location(new Coordinates(51.596696, 24.369107), new Coordinates(56.348645, 25.005892));                

                stream.MatchingTweetReceived += (sender, a) =&gt;
                    if (a.Tweet.CreatedAt.Day == DateTime.Now.Day)
                            InsertTweet(a.Tweet.Text, a.Tweet.CreatedBy.Location == null ? string.Empty : a.Tweet.CreatedBy.Location);
                        catch (Exception ex)
                            Console.WriteLine("Error "  + ex.ToString());

                var StreamThread = new Thread(() =&gt; stream.StartStreamMatchingAnyCondition());



        public static void InsertTweet(string tweet, string location)
            cmd = new SqlCommand("UpdateMood", con);
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.AddWithValue("@Hour", DateTime.Now.Hour);
            cmd.Parameters.AddWithValue("@Date", DateTime.Now.ToString("yyyy-MM-dd"));

            if (tweet.Contains("😀") || tweet.Contains("😁") || tweet.Contains("😂") || tweet.Contains("😃") || tweet.Contains("😄") || tweet.Contains("😆")
                || tweet.Contains("😉") || tweet.Contains("😎") || tweet.Contains("😍") || tweet.Contains("☺") || tweet.Contains("🙂") || tweet.Contains("😇")
                || tweet.Contains("🎉") || tweet.Contains("😊") || tweet.Contains("😋") || tweet.Contains("😘") || tweet.Contains("😗") || tweet.Contains("😙")
                || tweet.Contains("😚") || tweet.Contains("☺") || tweet.Contains("😜") || tweet.Contains("😝"))
                cmd.Parameters.AddWithValue("@Mood", "Happy");

            if (tweet.Contains("🙁") || tweet.Contains("😦") || tweet.Contains("🙍") || tweet.Contains("😠") || tweet.Contains("😡") || tweet.Contains("💢")
                || tweet.Contains("🗯") || tweet.Contains("😥") || tweet.Contains("😫") || tweet.Contains("😔") || tweet.Contains("😕")
                || tweet.Contains("☹") || tweet.Contains("😖") || tweet.Contains("😞") || tweet.Contains("😟") || tweet.Contains("😢")
                || tweet.Contains("😭") || tweet.Contains("😦") || tweet.Contains("😧") || tweet.Contains("😨") || tweet.Contains("😩")
                || tweet.Contains("😰"))
                cmd.Parameters.AddWithValue("@Mood", "Stressed");
                InsertTweetEntry(tweet, location);

            if (tweet.Contains("✍") || tweet.Contains("✍🏼") || tweet.Contains("📔") || tweet.Contains("📕") || tweet.Contains("📖") || tweet.Contains("📗")
                || tweet.Contains("📘") || tweet.Contains("📙") || tweet.Contains("📚") || tweet.Contains("📓"))
                cmd.Parameters.AddWithValue("@Mood", "Studying");
                InsertTweetEntry(tweet, location);

            if (tweet.Contains("🍔") || tweet.Contains("🍟") || tweet.Contains("🍕") || tweet.Contains("🍲") || tweet.Contains("🍚") || tweet.Contains("🍛")
                || tweet.Contains("🍜") || tweet.Contains("🍝") || tweet.Contains("🍠") || tweet.Contains("🍣") || tweet.Contains("🍽") || tweet.Contains("🍷")
                || tweet.Contains("🍸") || tweet.Contains("🍴"))
                cmd.Parameters.AddWithValue("@Mood", "Hungry");
                InsertTweetEntry(tweet, location);

            if (tweet.Contains("💻") || tweet.Contains("🖥") || tweet.Contains("🎥") || tweet.Contains("📺") || tweet.Contains("▶") || tweet.Contains("◀"))                
                cmd.Parameters.AddWithValue("@Mood", "Youtubing");
                InsertTweetEntry(tweet, location);

            if (tweet.Contains("⚽") || tweet.Contains("⚾") || tweet.Contains("🏀") || tweet.Contains("🏈") || tweet.Contains("🏉") || tweet.Contains("📣")
                || tweet.Contains("📯"))
                cmd.Parameters.AddWithValue("@Mood", "Cheering");
                InsertTweetEntry(tweet, location);


        private static void InsertTweetEntry(string tweet, string location)
            //Finally record the tweet
            cmd = new SqlCommand("InsertTweet", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@Tweet", tweet);
            cmd.Parameters.AddWithValue("@Location", location);
            int index = cmd.ExecuteNonQuery();            

Hope you liked it. Stay tuned for more such posts!