Posts Tagged ‘Flickr’

Silverlight 2.0 Flickr WordPress Widget

Tuesday, April 8th, 2008

I had the challenge of creating both a simple Silverlight 2.0 flickr viewer and a WordPress widget that used silverlight so I combined the two projects in to one.

The first part was creating the Silverlight 2.0 Flickr RSS viewer.

   1: <UserControl
   2:     xmlns="http://schemas.microsoft.com/client/2007"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     x:Class="FlickrShow.Page"
   5:     Width="auto" 
   6:     Height="auto" 
   7:     x:Name="FlickrShow" 
   8:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
   9:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
  10:     mc:Ignorable="d">
  11:  
  12:     <Grid x:Name="LayoutRoot" Background="#FF424242" >
  13:         <Image HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="ImageItem" VerticalAlignment="Stretch" Stretch="Uniform" Cursor="Hand" Source="OpeningImage.jpg">
  14:             <Image.Resources>
  15:                 <Storyboard x:Name="FadeOutAnimation">
  16:                     <DoubleAnimation Duration="00:00:00.20" From="1" To="0"                        
  17:                                      Storyboard.TargetProperty="Opacity"                        
  18:                                      Storyboard.TargetName="BigImage" />
  19:                 </Storyboard>
  20:                 <Storyboard x:Name="FadeInAnimation">
  21:                     <DoubleAnimation Duration="00:00:00.20" From="0" To="1"                        
  22:                                      Storyboard.TargetProperty="Opacity"                        
  23:                                      Storyboard.TargetName="BigImage" />
  24:                 </Storyboard>
  25:             </Image.Resources>
  26:         </Image>
  27:         <TextBox Height="30" VerticalAlignment="Bottom" Text="" x:Name="LabelBox" Background="#2B000000" Foreground="#FFFFFFFF" BorderThickness="0,0,0,0" FontSize="11" />
  28:     </Grid>
  29: </UserControl>

page.xaml

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Windows;
   5: using System.Windows.Controls;
   6: using System.Windows.Documents;
   7: using System.Windows.Input;
   8: using System.Windows.Media;
   9: using System.Windows.Media.Animation;
  10: using System.Windows.Shapes;
  11: using System.Windows.Threading;
  12: using System.Windows.Browser;
  13: using System.Xml.Linq;
  14: using System.Windows.Media.Imaging;
  15: using System.Windows.Resources;
  16: using System.IO;
  17: using System.Net;
  18: using System.Xml;
  19: using System.ServiceModel.Syndication;
  20:  
  21:  
  22:  
  23: namespace FlickrShow
  24: {
  25:     public class SettingDefinition
  26:     {
  27:         public string userID { get; set; }
  28:         public string feedType  { get; set; }
  29:         public string tags  { get; set; }
  30:         public string duration { get; set; }
  31:     }
  32:  
  33:     public partial class Page : UserControl
  34:     {
  35:         string currentUserID;
  36:         string currentFeedType;
  37:         string currentTags;
  38:         int currentDuration;
  39:  
  40:         DateTime lastUpdate;
  41:         string currentLink;
  42:         String[,] imgArray = new String[20, 3]; //Array to store information pulled from the RSS
  43:         int i = 0;  //handy little index number to count with
  44:         int imageIndex = 0;  //another index used for displaying specific images
  45:         DispatcherTimer dt = new DispatcherTimer();
  46:         
  47:         public Page(string UserID, string FeedType, string Tags, int Duration)
  48:         {
  49:             InitializeComponent();
  50:  
  51:             currentUserID = UserID;
  52:             currentFeedType = GetFeedType(FeedType);
  53:             currentTags = Tags;
  54:             currentDuration = Duration;
  55:  
  56:             this.Loaded += new RoutedEventHandler(Page_Loaded);
  57:             HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri("http://api.flickr.com/services/feeds/" + currentFeedType + currentUserID + currentTags + "&format=rss2"));
  58:  
  59:             request.BeginGetResponse(new AsyncCallback(getImages), request);
  60:  
  61:             lastUpdate = DateTime.Now;
  62:  
  63:             dt.Interval = new TimeSpan(0, 0, 0, currentDuration);
  64:             dt.Tick += new EventHandler(dt_Tick);
  65:             dt.Start();
  66:  
  67:         }
  68:  
  69:         void getImages(IAsyncResult asyncResult)
  70:         {
  71:             XNamespace mediaNamespace = "http://search.yahoo.com/mrss/";
  72:  
  73:  
  74:             HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
  75:             HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
  76:  
  77:             XmlReader reader = XmlReader.Create(response.GetResponseStream());
  78:             SyndicationFeed feed = SyndicationFeed.Load(reader);
  79:  
  80:             foreach (SyndicationItem item in feed.Items)
  81:             {
  82:                 //let's put the results in a multidimesional Array, because they are fun 
  83:                 imgArray.SetValue(item.ElementExtensions[1].GetReader().GetAttribute("url"), i, 0);
  84:                 imgArray.SetValue(item.Title.Text, i, 1);
  85:                 imgArray.SetValue("http://www.flickr.com" + item.Links[0].Uri.AbsolutePath, i, 2);
  86:                 i++;
  87:             }
  88:         }
  89:  
  90:         void Page_Loaded(object sender, RoutedEventArgs e)
  91:         {
  92:                       
  93:             ImageItem.MouseEnter += new MouseEventHandler(ImageItem_MouseEnter);
  94:             ImageItem.MouseLeave += new MouseEventHandler(ImageItem_MouseLeave);
  95:             ImageItem.MouseLeftButtonDown += new MouseButtonEventHandler(ImageItem_MouseButtonDown);
  96:  
  97:             
  98:         }
  99:  
 100:  
 101:  
 102:         void dt_Tick(object sender, EventArgs e)
 103:         {
 104:             //this is our timer control, every time we update this will run
 105:             Update();   
 106:         }
 107:  
 108:         void Update()
 109:         {
 110:             //Updating the time
 111:             DateTime now = DateTime.Now;
 112:             TimeSpan elapsed = now - lastUpdate;
 113:             lastUpdate = now;
 114:             //do your loop processing here
 115:             ChangeImage();
 116:             
 117:         }
 118:  
 119:         void ChangeImage()
 120:         {
 121:             //This is where we actually update the <image> XAML. 
 122:  
 123:             if (imageIndex <= (i - 1))
 124:             {
 125:                 LabelBox.Text = imgArray.GetValue(imageIndex, 1) as string;
 126:                 ImageItem.SetValue(Image.SourceProperty, imgArray.GetValue(imageIndex, 0) as string);
 127:                 currentLink = imgArray.GetValue(imageIndex, 2) as string;
 128:                 imageIndex++;
 129:             }
 130:             else
 131:             {
 132:                 imageIndex = 0;
 133:                 LabelBox.Text = imgArray.GetValue(imageIndex, 1) as string;
 134:                 ImageItem.SetValue(Image.SourceProperty, imgArray.GetValue(imageIndex, 0) as string);
 135:                 currentLink = imgArray.GetValue(imageIndex, 2) as string;
 136:                 imageIndex++;
 137:             }
 138:  
 139:         }
 140:  
 141:         public string GetFeedType(string feedSetting)
 142:         {
 143:             switch (feedSetting)
 144:                 {
 145:                 case "Public":
 146:                         return "photos_public.gne?id=";                        
 147:                 case "Friends":
 148:                     //This is for a future release
 149:                         return "photos_friends.gne?user_id=";
 150:                 default:
 151:                         return "photos_public.gne?id="; 
 152:                 }
 153:             
 154:         }
 155:  
 156:         public string FormatTags(string tagsElement)
 157:         {
 158:             if (tagsElement.Length > 0)
 159:             {
 160:                 return "&tags=" + tagsElement;
 161:             }
 162:             else { return ""; }
 163:         }
 164:  
 165:         private void ImageItem_MouseEnter(object sender, MouseEventArgs e)
 166:         {            
 167:                 dt.Stop();
 168:         }
 169:  
 170:         private void ImageItem_MouseLeave(object sender, MouseEventArgs e)
 171:         {
 172:             dt.Start();
 173:         }
 174:  
 175:         private void ImageItem_MouseButtonDown(object sender, MouseButtonEventArgs e)
 176:         {
 177:             HtmlPage.Window.Navigate(new Uri(currentLink, UriKind.Absolute), "_flickr");
 178:         }
 179:     }
 180: }

page.xaml.cs

   1: using System.Windows;
   2: using System;
   3:  
   4: namespace FlickrShow
   5: {
   6:     public partial class App : Application 
   7:     {
   8:  
   9:         public App() 
  10:         {
  11:             this.Startup += this.OnStartup;
  12:             this.Exit += this.OnExit;
  13:  
  14:             InitializeComponent();
  15:         }
  16:  
  17:         private void OnStartup(object sender, StartupEventArgs e) 
  18:         {
  19:             // Load the main control here
  20:             string currentUserID = e.InitParams["flickr_userID"];
  21:             string currentFeedType = "Public";
  22:             string currentTags = "";
  23:             int currentDuration = Convert.ToInt32(e.InitParams["time"]);
  24:  
  25:             this.RootVisual = new Page(currentUserID, currentFeedType, currentTags, currentDuration);
  26:         }
  27:  
  28:         private void OnExit(object sender, EventArgs e) 
  29:         {
  30:  
  31:         }
  32:     }
  33: }

App.xaml.cs

   1: <?php
   2: /*
   3: Plugin Name: Silverlight Flickr Widget
   4: Plugin URI: http://www.futile.com/
   5: Description: A widget which will display your latest Flickr photos using Silverlight.
   6: Author: Ryan T. Lane
   7: Version: 0.2
   8: Author URI: http://futile.com/
   9: 
  10: Installing
  11: 1. Make sure you have the Widget plugin available at http://automattic.com/code/widgets/
  12: 1. Copy wordpressWidgetSilverlightFlickr.php to your plugins folder, /wp-content/plugins/widgets/
  13: 2. Activate it through the plugin management screen.
  14: 3. Go to Themes->Sidebar Widgets and drag and drop the widget to wherever you want to show it.
  15: 
  16: Changelog
  17: 0.2 = First public release.
  18: */
  19:  
  20:  
  21: function WidgetFlickrSilverlight($args) {
  22:     extract($args);
  23:     
  24:     $options = get_option('WidgetFlickrSilverlight');
  25:     if( $options == false ) {
  26:         $options[ 'flickr_userID' ] = '21854617@N00';
  27:         $options[ 'time' ] = 4;
  28:     }
  29:     
  30:     $time = $options[ 'time' ];
  31:     $flickr_userID = $options[ 'flickr_userID' ];
  32:     
  33:     echo $before_widget;
  34:     
  35:     echo $before_title . 'Flickr' . $after_title; 
  36:     ?>
  37:                <script type="text/javascript">
  38:                     function onSilverlightError(sender, args) {
  39:                     if (args.errorType == "InitializeError")  {
  40:                         var errorDiv = document.getElementById("errorLocation");
  41:                         if (errorDiv != null)
  42:                         errorDiv.innerHTML = args.errorType + "- " + args.errorMessage;
  43:                         }
  44:                     }
  45:                 </script>
  46:                 
  47:                 <!-- Runtime errors from Silverlight will be displayed here.
  48:                     This will contain debugging information and should be removed or hidden when debugging is completed -->
  49:                 <div id='errorLocation' style="font-size: small;color: Gray;"></div>
  50:  
  51:                 <div id="silverlightControlHost">
  52:                     <object data="data:application/x-silverlight," type="application/x-silverlight-2-b1" width="100%" height="100%">
  53:                         <param name="source" value="/wp-content/plugins/widgets/FlickrShow.xap"/>
  54:                         <param name="onerror" value="onSilverlightError" />
  55:                         <param name="background" value="white" />
  56:                         <param name="initParams" value="time=<?php echo $time; ?>,flickr_userID=<?php echo $flickr_userID; ?>" />
  57:                         
  58:                         <a href="http://go.microsoft.com/fwlink/?LinkID=108182" style="text-decoration: none;">
  59:                              <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
  60:                         </a>
  61:                     </object>
  62:                     <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
  63:                 </div>   
  64:         <?php echo $after_widget; ?>
  65: <?php
  66: }
  67:  
  68: function WidgetFlickrSilverlight_control() {
  69:     $options = $newoptions = get_option('WidgetFlickrSilverlight');
  70:     if( $options == false ) {
  71:         $newoptions[ 'title' ] = 'Flickr Photos';
  72:     }
  73:     if ( $_POST["flickr-submit"] ) {
  74:         $newoptions['title'] = strip_tags(stripslashes($_POST["flickr-title"]));
  75:         $newoptions['time'] = strip_tags(stripslashes($_POST["time"]));
  76:         $newoptions['flickr_userID'] = strip_tags(stripslashes($_POST["flickr-userID"]));
  77:     }
  78:     if ( $options != $newoptions ) {
  79:         $options = $newoptions;
  80:         update_option('WidgetFlickrSilverlight', $options);
  81:     }
  82:     $title = wp_specialchars($options['title']);
  83:     $time = wp_specialchars($options['time']);
  84:     if ( empty($items) || $items < 1 ) $items = 3;
  85:     $flickr_userID = wp_specialchars($options['flickr_userID']);
  86:  
  87: ?>
  88:     <p><label for="flickr-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="flickr-title" name="flickr-title" type="text" value="<?php echo $title; ?>" /></label></p>
  89:     <p><label for="flickr-userID"><?php _e('Flickr User ID:'); ?> <input style="width: 250px;" id="flickr-title" name="flickr-userID" type="text" value="<?php echo $flickr_userID; ?>" /></label></p>
  90:     <p style="text-align:center; line-height: 30px;"><?php _e('Time per image in seconds:'); ?> <select id="time" name="time"><?php for ( $i = 1; $i <= 10; ++$i ) echo "<option value='$i' ".($time==$i ? "selected='selected'" : '').">$i</option>"; ?></select></p>
  91:     <p align='left'>
  92:     * Your user ID can be found on your Flickr RSS page. Scroll down to the bottom of the page until you see the <em>Feed</em> link and copy the value after id from the URL into the box above.<br />
  93:     <br clear='all'></p>
  94:     <input type="hidden" id="flickr-submit" name="flickr-submit" value="1" />
  95: <?php
  96: }
  97:  
  98:     function WidgetFlickrSilverlight_init() {
  99:         register_widget_control('Silverlight Flickr', 'WidgetFlickrSilverlight_control', 500, 250);
 100:         register_sidebar_widget('Silverlight Flickr', 'WidgetFlickrSilverlight');
 101:     }
 102:     add_action( "init", "WidgetFlickrSilverlight_init" );
 103:  
 104: ?>

wordpressWidgetSilverlightFlickr.php

 

The php page and compiled .xap files are placed in the /wp-content/plugins/widgets/ folder.

First you will have to activate the plug-in.

image

Then enable the widget in one of your sidebars and edit the properties to include your information.

image

if you don’t know your flickr user id you can get it from idGettr

That’s all for now.  I will do a more detailed write up of what is going on up above very soon.

You can grab the source from CodePlex.

Happy Valentine’s Day

Thursday, February 14th, 2008

Silverlight Valentine

I worked on a little Silverlight Valentine’s day e-card for Microsoft. The original card design was going to be a bit more, pills but we had some time constraints to deal with. Overall, tadalafil it’s a simple application. The meat of the developement work was done by the talented folks at Aeshen.

I would like to go back and really rework the concept more, but you know, I like to make code and design perfect and the real world demands that stuff ships on time. Enjoy. I hope everyone has a wonderful Valentine’s day.

xoxo
Ryan