This blog entry will be all about adding the projectitem to the SharpDevelop project. In SharpDevelop we get project service from the class "ProjectService" that lets us to add various type of project item to the SharpDevelop project and bind to the the different project related events. ProjectService class can be found in main base addin ("\Project\Src\Services\ProjectService\ProjectService.cs"). SharpDevelop project item can be of different types like cs/vb files , project references , webreferences etc. Main base class for all the project items in SharpDevelop is "ProjectItem" Class from which all the derived project item classes evolve like FileProjectItem, ReferenceProjectItem, WebReferenceProjectItem etc.
In this blog we will see the addition of assembly references and the addition of cs/vb class files to the SharpDevelop Project at runtime.
Once the project is opened in the SharpDevelop we can access the current project via ProjectService class ( "ProjectService.CurrentProject" property ).
To add the assembly reference at runtime we have to create the instance of ReferenceProjectItem and provide the current project instance and the assembly name in the constructor.
ReferenceProjectItem item = new ReferenceProjectItem(ProjectService.CurrentProject, Path.GetFileNameWithoutExtension(my_exsistingCSFilePath));
Prior to adding the assembly reference to the Project , we can check if assembly reference is already added to the Project. We can check that by checking all the current project items .
IProject project = ProjectService.CurrentProject;
ProjectItem proitem = (from proI in project.Items.AsEnumerable() where Path.GetFileNameWithoutExtension(proI.FileName) == Path.GetFileNameWithoutExtension (my_exsistingCSFilePath) select proI).SingleOrDefault();
if (proitem != null){ ProjectService.RemoveProjectItem(project, proitem);
}
After checking for the exsistence of the assembly reference we can add the assembly reference to the Project at runtime by:-
ProjectService.AddProjectItem(project, item);
project.Save();
ProjectBrowserPad.RefreshViewAsync();
To add the cs/vb project item to Project at runtime , we have to create the instance of "FileProjectItem" and provide appropriate parameters to the constructor.
IProject project = ProjectService.CurrentProject;
string relFileName = FileUtility.GetRelativePath(project.Directory, filePath);
FileProjectItem fileProjectItem = new FileProjectItem(project, project.GetDefaultItemType(filePath), relFileName);
Then we can add the file to the current project , following the same procedure as we did in addition of assembly reference.
ProjectItem item = (from proI in project.Items.AsEnumerable() where Path.GetFileName(proI.FileName) == Path.GetFileName(filePath) select proI).SingleOrDefault();
if(item != null) {ProjectService.RemoveProjectItem(project, item); }
FileNode fileNode = new FileNode(filePath, FileNodeStatus.InProject);
fileNode.ProjectItem = fileProjectItem; ProjectService.AddProjectItem(project, fileProjectItem); project.Save(); ProjectBrowserPad.RefreshViewAsync();
In this same way we can add WebReferences and all other project items to the SharpDevelop Project.
Monday, October 25, 2010
Friday, October 22, 2010
SharpDevelop :- ReferencePath
Adding Referencepath property to the SharpDevelop project property page programmatically. This is the topic of this blog. I wanted to add runtime generated reference path to the project property page. SharpDevelop provide Project service for managing the project related funtionality. ProjectService class contains many static method and events that can be used to load the new project to the solution or add exsisting project to the solution. ProjectService also exposes many events that are raised when project is added.removed or projectitem are added or removed.
I decided to add the dynamically generated reference path to the project after the project is loaded inside the SharpDevelop. For this I subscribed to the ProjectCreated event of ProjectService class .
ProjectService.ProjectCreated -= new ProjectEventHandler(ProjectService_ProjectCreated);
So whenever a new project is added to the solution , i can get the event and add my reference path to the project property. When we get the ProjectCreated event we get the ProjectEventArgs as the parameter. ProjectEventArgs contains the property Project which is of type IProject . We have to cast the Project property to MSBuildBasedProject .
MSBuildBasedProject is class that is responsible for the generating and setting the MSBuild items and properties from the in memory representation of project and project items.
Now we have to call the SetProperty method of MSBuildBasedProject with proper property /value and call the Save method on the MSBuildBasedProject.
void ProjectService_ProjectCreated(object sender, ProjectEventArgs e){
MSBuildBasedProject msProject = e.Project as MSBuildBasedProject;
msProject.SetProperty("ReferencePath", myRefPath);
msProject.Save();
}
I decided to add the dynamically generated reference path to the project after the project is loaded inside the SharpDevelop. For this I subscribed to the ProjectCreated event of ProjectService class .
ProjectService.ProjectCreated -= new ProjectEventHandler(ProjectService_ProjectCreated);
So whenever a new project is added to the solution , i can get the event and add my reference path to the project property. When we get the ProjectCreated event we get the ProjectEventArgs as the parameter. ProjectEventArgs contains the property Project which is of type IProject . We have to cast the Project property to MSBuildBasedProject .
MSBuildBasedProject is class that is responsible for the generating and setting the MSBuild items and properties from the in memory representation of project and project items.
Now we have to call the SetProperty method of MSBuildBasedProject with proper property /value and call the Save method on the MSBuildBasedProject.
void ProjectService_ProjectCreated(object sender, ProjectEventArgs e){
MSBuildBasedProject msProject = e.Project as MSBuildBasedProject;
msProject.SetProperty("ReferencePath", myRefPath);
msProject.Save();
}
Thursday, October 21, 2010
SharpDevelop :-- Project Template
This blog is about creating custom project template and integrating it with the SharpDevelop Studio. Whenever we wanted to create a new project whether it is winform project , class library ,usercontrol etc ,we are presented with predefined project template in New Project Dialog Box. In Visual studio or VSTA the project templates are the msbuild project templates and are installed with the IDE . ShareDevelop project templates are the custom project template files similar to the VS templates with xml format. PropertyService of SharpDevelop contains all the info about the configurable and global properties. To get the path of the SharpDevelop project templates we can use PropertyService to find the path. PropertyService member DataDirectory gives us the location where project and file templates are stored .
So SharpDevelop project templates are stored at location :--
Path.Combine(PropertyService.DataDirectory, "templates", "project");
Under this path there are folders named "CSharp" and "VBNet" .These folder contains the respective project template for these languages. SharpDevelop project templates are xml file with extension ".xpt".
Lets examine the project template for example "FormsProject.xpt" .
We can see that SharpDevelop Project Template is similar to the msbuild project template. There is opening node "Template" that has some attribute defining the general info about the template. Then comes the "TemplateConfiguration" that tells the template configuration :-
Name :- name of the template
Category :- the main folder under which to show this template in New Project Dialogbox.
SubCategory :- the folder under main folder under which to show this project template in New Project Dialog box.
Icon :- icon to show on the project template shown in New Project Dialogbox.
Supported target framework :- the .net target framework.
"Actions" node tells us which file to open up in ShareDevelop IDE when the project template is loaded. It defines the child node "Open" with attribute "filename" that defines the file to open in SharpDevelop workspace after the project is loaded. Then comes the node "Project" defining the attribute "language" .
Under Project node comes "ProjectItems" which contains the child nodes of type "reference". These nodes of type "reference" tells us what assemblies to add up as references to the project when it is loaded up in SharpDevelop IDE.
Project node also contain the child node "PropertyGroup" which contains the node about the information of the project type (exe or library) under node "OutputType".
In case of msbuild project templates we have code file (.cs or .vb) in separate files and info of these file are stored in project templates. But in SharpDevelop the code files to generate along with the project are defined inside the project template. "Project" node in project template defines the node "Files" which in turn contains the child nodes "File". "File" node contains the attributes name and language defiining the name and language of .cs or .vb file . Under "File" node there is CDATA section which contains all the code for file .
Now lets see how these templates are loaded in SharpDevelop. We can locate the New Project DialogBox under the base addin code (ICSharpCode.SharpDevelop.Project.Dialogs) . Base addin is the project (ICSharpCode.SharpDevelop.csproj) and New Project DialogBox is located at "\src\gui\dialogs". The constructor of New Project DialogBox contains the method "InitializeTemplates()" . In this method project templates are iterated and filled up in the listview of the NewProject DialogBox. The collection of project templates are fetched from the ProjectTemplate class's public property "ProjectTemplates". If we go inside the ProjectTemplate class and look at ProjectTemplates property we can see the get part of property returns ProjectTemplate Collection after calling the "UpdateTemplate()" method.
"UpdateTemplate()" method is responsible for creating the project template collection.It contains the code to load all the project templates from the DataDirectory and create in memory representation of project template xml files. So the instance of class ProjectTemplate is the runtime representation of the project template files residing in the DataDirectory.
ProjectTemplate class also contains the public property ProjectDescriptor , this property is of type "ProjectDiscriptor". Instance of ProjectDiscriptor class is also created by the Project template class and it contains the information about the files of the Project . ProjectDiscriptor class holds the in memory representation of the file node in the ProjectTemplate xml file.
So to create our own project template we have to create the ".xpt" xml project template file and place it in the DataDirectory under relative language folder (CSharp or VBNet). SharpDevelop will automatically load the project when the New Project DialogBox is opend.
If your project files are generated at runtime from other system and you have to create new project template based on them , then you have to create the project template at runtime and save it to the DataDirectory. Then you have to call the static method UpdateTemplate() of ProjectTemplate class to reload the Project template .
So SharpDevelop project templates are stored at location :--
Path.Combine(PropertyService.DataDirectory, "templates", "project");
Under this path there are folders named "CSharp" and "VBNet" .These folder contains the respective project template for these languages. SharpDevelop project templates are xml file with extension ".xpt".
Lets examine the project template for example "FormsProject.xpt" .
<Template created="06/10/2001" templateType="MyTemplateCS">
<TemplateConfiguration>
<Name>MyTemplate</Name>
<Category>C#</Category>
<Subcategory>MyCatagory</Subcategory>
<Icon>C#.Project.Library</Icon>
<Description>Template for Workflow.</Description>
<SupportedTargetFrameworks>v2.0;v3.5Client</SupportedTargetFrameworks>
</TemplateConfiguration>
<Actions>
<Open filename="Main.cs" />
</Actions>
<Project language="C#">
<ProjectItems>
<Reference Include="System" />
<Reference Include="System.Data" />
</PROJECTITEMS/> language=C# name="Data_Buzz.cs"Library<> <> >
<![CDATA[
/* Our code goes here */
]]>
<</File>
</Files>
</Project>
</Template>
We can see that SharpDevelop Project Template is similar to the msbuild project template. There is opening node "Template" that has some attribute defining the general info about the template. Then comes the "TemplateConfiguration" that tells the template configuration :-
Name :- name of the template
Category :- the main folder under which to show this template in New Project Dialogbox.
SubCategory :- the folder under main folder under which to show this project template in New Project Dialog box.
Icon :- icon to show on the project template shown in New Project Dialogbox.
Supported target framework :- the .net target framework.
"Actions" node tells us which file to open up in ShareDevelop IDE when the project template is loaded. It defines the child node "Open" with attribute "filename" that defines the file to open in SharpDevelop workspace after the project is loaded. Then comes the node "Project" defining the attribute "language" .
Under Project node comes "ProjectItems" which contains the child nodes of type "reference". These nodes of type "reference" tells us what assemblies to add up as references to the project when it is loaded up in SharpDevelop IDE.
Project node also contain the child node "PropertyGroup" which contains the node about the information of the project type (exe or library) under node "OutputType".
In case of msbuild project templates we have code file (.cs or .vb) in separate files and info of these file are stored in project templates. But in SharpDevelop the code files to generate along with the project are defined inside the project template. "Project" node in project template defines the node "Files" which in turn contains the child nodes "File". "File" node contains the attributes name and language defiining the name and language of .cs or .vb file . Under "File" node there is CDATA section which contains all the code for file .
Now lets see how these templates are loaded in SharpDevelop. We can locate the New Project DialogBox under the base addin code (ICSharpCode.SharpDevelop.Project.Dialogs) . Base addin is the project (ICSharpCode.SharpDevelop.csproj) and New Project DialogBox is located at "\src\gui\dialogs". The constructor of New Project DialogBox contains the method "InitializeTemplates()" . In this method project templates are iterated and filled up in the listview of the NewProject DialogBox. The collection of project templates are fetched from the ProjectTemplate class's public property "ProjectTemplates". If we go inside the ProjectTemplate class and look at ProjectTemplates property we can see the get part of property returns ProjectTemplate Collection after calling the "UpdateTemplate()" method.
"UpdateTemplate()" method is responsible for creating the project template collection.It contains the code to load all the project templates from the DataDirectory and create in memory representation of project template xml files. So the instance of class ProjectTemplate is the runtime representation of the project template files residing in the DataDirectory.
ProjectTemplate class also contains the public property ProjectDescriptor , this property is of type "ProjectDiscriptor". Instance of ProjectDiscriptor class is also created by the Project template class and it contains the information about the files of the Project . ProjectDiscriptor class holds the in memory representation of the file node in the ProjectTemplate xml file.
So to create our own project template we have to create the ".xpt" xml project template file and place it in the DataDirectory under relative language folder (CSharp or VBNet). SharpDevelop will automatically load the project when the New Project DialogBox is opend.
If your project files are generated at runtime from other system and you have to create new project template based on them , then you have to create the project template at runtime and save it to the DataDirectory. Then you have to call the static method UpdateTemplate() of ProjectTemplate class to reload the Project template .
Tuesday, October 19, 2010
SharpDevelop
Recently , I started working with the SharpDevelop , open source IDE for the .Net platform . It is same as NetBeans and Visual Studio IDE and provides almost same features . Previously I have worked on VSTA as tool for developing addin's for a application. VSTA is the subset of Visual studio and provided many ways to extend the IDE . I have done many customization in the IDE with VSTA programming interface. In VSTA using ENVDTE namespace we get hold of the extensibility framework for IDE and its funtionalities. We can provide our own custom menu, menuitems, toolbar,toolbar items , we can extend the contextmenus of IDE , get hold of many IDE command like build ,rebuild, edit many properties of the IDE like platform target, reference path, active configuration etc. Apart form all these we can define our own project templates, wizards (IDEWizards) etc and can add projects and project items at runtime. We can use CodeDom to generate code , create assemblies and build them.
Can I achieve same thing using ShareDevelop ? To find out that, I got source code of ShareDevelop and started digging it. Sharpdevelop is based on addin model . It consist of a small core and all its functionalities are held by addins . Core contains the code to extend the SharpDevelop via all the other addin's. SharpDevelop Addin's are simple xml files and the binaries associated with them (.dll etc). For example Addin name myaddin will have a single xml file with extension .addin :- myaddin.addin and one or more binaries having the implementation of addin (myaddin.dll ). Xml file contain some nodes specific to the addin general information .Main thing to notice in addin xml are the extension nodes .Extension nodes starts with the name path which has the attribute named "name" that defines the path where this extension will be added up on the SharpDevelop core.
<path name="/SharpDevelop/Workspace/MainMenu">;
SharpDevelop contains this concept of paths . SharDevelop core and the addin responsible for the base functionality of the SharpDelvelop (ICSharpCode.SharpDevelop.addin) defines some paths upon which the functionalities can be extended. Paths represent the way via which we can find a node in a tree where "/" defines the root node. In fact the SharpDevelop maintains the tree structure for all the addin's that extend it . So we can extend the base with a addin and that addin will become the tree node for addin tree.If that addin defines a extension point then further a next addin can extend this addin. This features of extending a existing addin is not there in VSTA framework. SharpDevelop core contains many services for basic functionalities like property, resource, gui etc handling. Another concept other than paths are codons. In addin xml file we can find the codons as :--
-
We can see all the elements inside the path node . As i have said, path node defines the extension point in SharpDevelop and it also defines the node that will be added to MainMenu of SharpDevelop . What about the elements inside path node, they all are codons. Codons are the element that specify the behaviour of the elements inside the program. So path tells us the extension point and the menuitem "File" is added under this path node. Menuitem "File" also contains the element Menuitem "Seperator1 " and "Exit". These codons will arranged under the "File" codon which is under the MainMenu path. No we have a treenode under the path Mainmenu. What we get from example is that SharDevelop contains a AddIn Tree that contains the AddIn Tree Nodes , AddIn tree nodes conatin the AddIns and in turn Addins contain the Codons. Addin Tree contains various service to load the addins and build the tree. AddinTreeNode conatins the method BuildChildItems that returns the list of all the built codons from a addin. Addin class contains all the information about the codons inside it and all the info of assemblies needed to create the runtime object of the codon. It gets all this info from the xml file . Codon class contains a methos Buiditem that creates the runtime instance of the codon. So the built codon is the in memory representation of the codon item in addin xml file. Shardevelop core contains many builder and factory classes to load the assemblies containg the codon definitions and build the in memory tree for the Addin from addin xml file and entire AddIn tree.
But can I do all the stuff that I did with VSTA , described above at starting ? I think with the help of Base Addin i can start experimenting . In next post I will start with creating our own project template in SharpDevelop. Hope ,somebody will find it useful.
http://www.codeproject.com/KB/cs/ICSharpCodeCore.aspx
http://www.icsharpcode.net/opensource/sd/
http://sharpdevelop.codeplex.com/
Can I achieve same thing using ShareDevelop ? To find out that, I got source code of ShareDevelop and started digging it. Sharpdevelop is based on addin model . It consist of a small core and all its functionalities are held by addins . Core contains the code to extend the SharpDevelop via all the other addin's. SharpDevelop Addin's are simple xml files and the binaries associated with them (.dll etc). For example Addin name myaddin will have a single xml file with extension .addin :- myaddin.addin and one or more binaries having the implementation of addin (myaddin.dll ). Xml file contain some nodes specific to the addin general information .Main thing to notice in addin xml are the extension nodes .Extension nodes starts with the name path which has the attribute named "name" that defines the path where this extension will be added up on the SharpDevelop core.
<path name="/SharpDevelop/Workspace/MainMenu">;
SharpDevelop contains this concept of paths . SharDevelop core and the addin responsible for the base functionality of the SharpDelvelop (ICSharpCode.SharpDevelop.addin) defines some paths upon which the functionalities can be extended. Paths represent the way via which we can find a node in a tree where "/" defines the root node. In fact the SharpDevelop maintains the tree structure for all the addin's that extend it . So we can extend the base with a addin and that addin will become the tree node for addin tree.If that addin defines a extension point then further a next addin can extend this addin. This features of extending a existing addin is not there in VSTA framework. SharpDevelop core contains many services for basic functionalities like property, resource, gui etc handling. Another concept other than paths are codons. In addin xml file we can find the codons as :--
<Path name = "/SharpDevelop/Workspace/MainMenu">
<MenuItem id = "File" label = "&File">
<MenuItem id = "Separator1" label = "-"/>
<MenuItem id = "Exit"
label = "E&xit"
class = "NCvs.Gui.Commands.ExitCommand"/>
</MenuItem>
</Path>
-
We can see all the elements inside the path node . As i have said, path node defines the extension point in SharpDevelop and it also defines the node that will be added to MainMenu of SharpDevelop . What about the elements inside path node, they all are codons. Codons are the element that specify the behaviour of the elements inside the program. So path tells us the extension point and the menuitem "File" is added under this path node. Menuitem "File" also contains the element Menuitem "Seperator1 " and "Exit". These codons will arranged under the "File" codon which is under the MainMenu path. No we have a treenode under the path Mainmenu. What we get from example is that SharDevelop contains a AddIn Tree that contains the AddIn Tree Nodes , AddIn tree nodes conatin the AddIns and in turn Addins contain the Codons. Addin Tree contains various service to load the addins and build the tree. AddinTreeNode conatins the method BuildChildItems that returns the list of all the built codons from a addin. Addin class contains all the information about the codons inside it and all the info of assemblies needed to create the runtime object of the codon. It gets all this info from the xml file . Codon class contains a methos Buiditem that creates the runtime instance of the codon. So the built codon is the in memory representation of the codon item in addin xml file. Shardevelop core contains many builder and factory classes to load the assemblies containg the codon definitions and build the in memory tree for the Addin from addin xml file and entire AddIn tree.
But can I do all the stuff that I did with VSTA , described above at starting ? I think with the help of Base Addin i can start experimenting . In next post I will start with creating our own project template in SharpDevelop. Hope ,somebody will find it useful.
http://www.codeproject.com/KB/cs/ICSharpCodeCore.aspx
http://www.icsharpcode.net/opensource/sd/
http://sharpdevelop.codeplex.com/
Saturday, July 24, 2010
Python and Google App Engine
Quite from some time I was getting bored of working with .Net and for some recreational work I decided to start learning Python and google app engine (On Windows) .
After installing Google AppEngine for Python and Google data service,I was ready to dive in. Google app engine works on CGI standards. I decided to implement a feedback form and send mail to users informing them about other resources. I started with creating a working directory for my application.
Google app engine applications contains a configuration file (app.yaml) that tells about the runtime to use (in my case python) and the handlers that will redirect and process the request .
//////////////////////////////////
application: Feedback
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: feedback.py
/////////////////////////////////
In above app.yaml file url: section in handlers specify that request to the url /.* should be handled by the feedback.py python script file.
Google App engine web framework defines many modules that helps us to write handlers and processors for web requests.
Google Web application typically contains multiple classes that processes the request and generates the responses. WSGIApplication class instance is responsible for routing incoming request for a particular URL to one of the handler classes.Finally there is main method to start the application.
.
Above feedback (FeedBack.py) implementation contains two handlers classes (MainPage and FeedBack) inheriting the webapp.Requesthandler class. These classes implement the post and get method that handles the incoming requests. Self.request and Self.response are the objects that are used to get the request parameters and generate the response. Apart from the handlers classes, WSGIApplication instance is created that specifies the URL's mapped to the handler classes, debug=True specify to print the error info on page if any. Then there is main method that runs the application.
As configured in the app.yaml , the request at base Url initiate the feedBack.py, which then routes the request to the handler class , based on WSGIApplication mapping. Main handler displays the feedback form with post method and action equal to "/submit" url. On submitting the MainPage form , url is redirected to "/submit" url , which as defined in the WSGIApplication, routes the request to feedBack handler class. Feedback handler class creates the response and sends a mail to user.
To run the application we can use command line or Google App engine launcher.
Start the Google App engine Launcher and use add application option to add the working directory.Google App engine launcher provides a simple UI to run the application.
Google data services contains various modules that can be used to access and use various google services such as youtube , picasa , facebook etc. Routing mechanism is somewhat same as Asp.net MVC. What I found is that Google app engine development is tightly integrated with other google services and exposes rich api to interact with other google services.
Google App Engine
Python
After installing Google AppEngine for Python and Google data service,I was ready to dive in. Google app engine works on CGI standards. I decided to implement a feedback form and send mail to users informing them about other resources. I started with creating a working directory for my application.
Google app engine applications contains a configuration file (app.yaml) that tells about the runtime to use (in my case python) and the handlers that will redirect and process the request .
//////////////////////////////////
application: Feedback
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: feedback.py
/////////////////////////////////
In above app.yaml file url: section in handlers specify that request to the url /.* should be handled by the feedback.py python script file.
Google App engine web framework defines many modules that helps us to write handlers and processors for web requests.
Google Web application typically contains multiple classes that processes the request and generates the responses. WSGIApplication class instance is responsible for routing incoming request for a particular URL to one of the handler classes.Finally there is main method to start the application.
import cgi
from google.appengine.api import users
from google.appengine.api import mail
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<Body>
<form method="post" action="/submit">
Name:</br> <input type="Text" name='name' width="100" />
</p>
Address:</br> <input type="Text" name='address' width="100" />
</p>
Email: </br><input type="Text" name='email' width="100" />
</p>
FeedBack:
</p>
<textArea name="name" rows="4" cols="60"></textarea>
</p>
<input type="submit" value="Submit"/>
</form>
</body>
</html>""")
class FeedBack(webapp.RequestHandler):
def post(self):
self.response.out.write('<html><body>Thanks for your feed back.')
self.response.out.write(cgi.escape(self.request.get('name')))
self.response.out.write('
<p>Email has been sent to you containing
futher resources.Thanks.
</body></html>
')
mail.send_mail(sender="Example.com Support <support@example.com>",
to=cgi.escape(self.request.get('email')),
subject="Your account has been approved",
body="""
Hello : ' + cgi.escape(self.request.get('name'))
+ ' </p>You can access the following resources .
<a href="" >Res1</a>
""")
application = webapp.WSGIApplication(
[('/', MainPage),
('/submit', FeedBack)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
.
Above feedback (FeedBack.py) implementation contains two handlers classes (MainPage and FeedBack) inheriting the webapp.Requesthandler class. These classes implement the post and get method that handles the incoming requests. Self.request and Self.response are the objects that are used to get the request parameters and generate the response. Apart from the handlers classes, WSGIApplication instance is created that specifies the URL's mapped to the handler classes, debug=True specify to print the error info on page if any. Then there is main method that runs the application.
As configured in the app.yaml , the request at base Url initiate the feedBack.py, which then routes the request to the handler class , based on WSGIApplication mapping. Main handler displays the feedback form with post method and action equal to "/submit" url. On submitting the MainPage form , url is redirected to "/submit" url , which as defined in the WSGIApplication, routes the request to feedBack handler class. Feedback handler class creates the response and sends a mail to user.
To run the application we can use command line or Google App engine launcher.
Start the Google App engine Launcher and use add application option to add the working directory.Google App engine launcher provides a simple UI to run the application.
Google data services contains various modules that can be used to access and use various google services such as youtube , picasa , facebook etc. Routing mechanism is somewhat same as Asp.net MVC. What I found is that Google app engine development is tightly integrated with other google services and exposes rich api to interact with other google services.
Google App Engine
Python
Wednesday, July 7, 2010
Silverlight Video Streaming
Recently I was on as project , that involved playing the media files from the storage server in the browser. Silverlight was chosen to play the media files. Plan was to have a datagrid that shows media files filtered on the basis of date. After the user chooses the file , the file is fetched from the storage and played in the media element . Starting was the creation of the project structure , a silverlight application with asp.net project to host the silverlight application. In the silverlight application, a usercontrol with media element embedded is created.

<mediaelement name="media" mediafailed="MediaElement_MediaFailed" autoplay="True">
Media Element has the property source and a method SetSource that set's the media file to be played in the media element. Source property takes the Uri of the media file and the SetSource method takes stream to be played in the media element. Setting the Source property was not a choice as the media files resided on the other server . Silverlight media element Source proerty do not support file:// or UNC path to set media files , files have to be on the webserver hosting the web app. So the solution to get the media files from the storage server and stream them to the silverlight client was to use WCF media streaming. At the silverlight client we use SetSource method of media element to provide the media stream.
WCF service will be hosted along side the web project on IIS . WCF service for silverlight application are little bit different from the normal WCF applications. WCF service has to be silverlight enabled. To create the silverlight enabled service goto :- Add New Item --> Silverlight --> Silverlight enabled WCF service , this will create a svc service file with default structure . We will start with creating a service contract interface IVideoService , having a method GetVideoFile that takes a string as parameter and returns the stream object. Method is decorated with the OperationContract and WebGet attribute.
.
.
Now we create the implementation of the service contract by creating a class VideoService that implements the service contract . In silverlight enabled WCF service , we have attribute AspNetCompatibilityRequirements
on the service class. Service class implements the GetVideoFile method that takes as parameter the path of video (UNC or File://) and returns the filestream .
.
Now our service class is in place, we create the WCF configuration for wcf streaming.We use basicHttpBinding with transferMode set to streamed , we also increase the maxReceivedMessageSize .With the service hosted on web app the endpoint address is always relative to the web address (Example : http://localhost:2310/Default.aspx --> http://localhost:2310/myservice.svc).

At the silverlight client we add service reference to our WCF service and use proxy to get the media file and play it with media element.
VideoStreaming.VideoServiceClient client = new VideoStreaming.VideoServiceClient();
client.GetVideoCompleted += new EventHandler(client_GetVideoCompleted);
client.GetVideoAsync(@"\\Storage-pc\Files1\Encoded\myvideo.asf");

We also have to create a clientaccesspolicy file and place it with service (.svc) file for making service available across appdomain boundries.

Now we are all set to stream the media file.
Network Security Access Restrictions in Silverlight
Making a Service Available Across Domain Boundaries
WCF Streaming Message Transfer

<mediaelement name="media" mediafailed="MediaElement_MediaFailed" autoplay="True">
Media Element has the property source and a method SetSource that set's the media file to be played in the media element. Source property takes the Uri of the media file and the SetSource method takes stream to be played in the media element. Setting the Source property was not a choice as the media files resided on the other server . Silverlight media element Source proerty do not support file:// or UNC path to set media files , files have to be on the webserver hosting the web app. So the solution to get the media files from the storage server and stream them to the silverlight client was to use WCF media streaming. At the silverlight client we use SetSource method of media element to provide the media stream.
WCF service will be hosted along side the web project on IIS . WCF service for silverlight application are little bit different from the normal WCF applications. WCF service has to be silverlight enabled. To create the silverlight enabled service goto :- Add New Item --> Silverlight --> Silverlight enabled WCF service , this will create a svc service file with default structure . We will start with creating a service contract interface IVideoService , having a method GetVideoFile that takes a string as parameter and returns the stream object. Method is decorated with the OperationContract and WebGet attribute.
.
[ServiceContract]
public interface IVideoService
{
[OperationContract]
[WebGet(UriTemplate = "media/{name}")]
Stream GetVideo(String name);
}
.
Now we create the implementation of the service contract by creating a class VideoService that implements the service contract . In silverlight enabled WCF service , we have attribute AspNetCompatibilityRequirements
on the service class. Service class implements the GetVideoFile method that takes as parameter the path of video (UNC or File://) and returns the filestream .
[AspNetCompatibilityRequirements
(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class VideoService : IVideoService
{
public Stream GetVideo(String name)
{
if(File.Exists(name))
{
return File.OpenRead(name);
}
return null;
}
}
.
Now our service class is in place, we create the WCF configuration for wcf streaming.We use basicHttpBinding with transferMode set to streamed , we also increase the maxReceivedMessageSize .With the service hosted on web app the endpoint address is always relative to the web address (Example : http://localhost:2310/Default.aspx --> http://localhost:2310/myservice.svc).

At the silverlight client we add service reference to our WCF service and use proxy to get the media file and play it with media element.
VideoStreaming.VideoServiceClient client = new VideoStreaming.VideoServiceClient();
client.GetVideoCompleted += new EventHandler
client.GetVideoAsync(@"\\Storage-pc\Files1\Encoded\myvideo.asf");

We also have to create a clientaccesspolicy file and place it with service (.svc) file for making service available across appdomain boundries.
Now we are all set to stream the media file.
Network Security Access Restrictions in Silverlight
Making a Service Available Across Domain Boundaries
WCF Streaming Message Transfer
Saturday, June 5, 2010
WPF DockingManager :- AvalonDock
Some days ago , I was in need of a docking panel for a WPF project. I needed the collapse and expand functionality , floating windows etc . I was familiar with the DockingManager component from DevExpress for Win forms and wanted same type of functionality for my WPF project. So while searching I came across a open source initiative AvalonDock on CodePlex, it was quite the thing that I wanted.
I implemented the DockingManager of AvalonDock and got my Window working with several floating and dockable windows.
After making my main window have many dockable and floating windows , I needed another functionality , that was to make visibility off for close buttton on Dockablepane , apart from that I also wanted to style the Documentpane and Dockablepane . To make the close button visibility off for Dockablepane and Documentpane, there's the property IsCloseable on DocumentContent and DockableContent.
Using this property we can change the close button's visibility. To disable the floating of windows in DocumentPane , there is another property IsFloatingAllowed on DocumentContent . But there is no property to disable the floating of DockablePane yet. To style the DocumentPane and DockablePane I relied upon the Expression Blend. After opening my project in Expression blend , I navigated to the DockablePane and DocumentPane in Visual Tree and used the option "Edit Copy of Template". This option make's the default style of DocumentPane and DockablePane available to us, Now you are free to edit the style as you like. The default style contains the Control template for both DockablePane and DocumentPane in their respective styles. We can edit them to get our desired look .
But there is one issue , after we save our project in Expression Blend with edited styles, it seems that Expression Blend removes the command binding from the style of DockablePane for Close Button and AutoHide Button. So if we run the application you will notice that close and autohide button on DocakblePane no longer works. The solution is to reintroduce the command binding for close and autohide button by specifying Command="ad:DockablePane.ToggleAutoHideCommand" and Command="ad:DockablePane.CloseCommand" in the respective xaml Button tags.
.
There is another catch , all the edited style that we have applied on DockablePane gets removed once the DockablePane is in floating state . So once the DockablePane is dragged in floating state , all the style is lost. To get around this problem we can use StateChanged event fired by the DockablePane whenever the state is changed from Docked to floating and vice-versa.
I implemented the DockingManager of AvalonDock and got my Window working with several floating and dockable windows.
After making my main window have many dockable and floating windows , I needed another functionality , that was to make visibility off for close buttton on Dockablepane , apart from that I also wanted to style the Documentpane and Dockablepane . To make the close button visibility off for Dockablepane and Documentpane, there's the property IsCloseable on DocumentContent and DockableContent.
Using this property we can change the close button's visibility. To disable the floating of windows in DocumentPane , there is another property IsFloatingAllowed on DocumentContent . But there is no property to disable the floating of DockablePane yet. To style the DocumentPane and DockablePane I relied upon the Expression Blend. After opening my project in Expression blend , I navigated to the DockablePane and DocumentPane in Visual Tree and used the option "Edit Copy of Template". This option make's the default style of DocumentPane and DockablePane available to us, Now you are free to edit the style as you like. The default style contains the Control template for both DockablePane and DocumentPane in their respective styles. We can edit them to get our desired look .
But there is one issue , after we save our project in Expression Blend with edited styles, it seems that Expression Blend removes the command binding from the style of DockablePane for Close Button and AutoHide Button. So if we run the application you will notice that close and autohide button on DocakblePane no longer works. The solution is to reintroduce the command binding for close and autohide button by specifying Command="ad:DockablePane.ToggleAutoHideCommand" and Command="ad:DockablePane.CloseCommand" in the respective xaml Button tags.
<ad:DockingManager x:Name="dockManager" RenderTransformOrigin="0,0">
<ad:ResizingPanel Orientation="Vertical" >
<ad:ResizingPanel Orientation="Horizontal" >
<ad:DockablePane
x:Name="story" Style="{DynamicResource DockablePaneStyleMosaic}">
<ad:DockableContent StateChanged="Live_StateChanged"
IsCloseable="False" DockableStyle="DockableToBorders" Title="Live">
</ad:DockableContent>
</ad:DockablePane>
<ad:DocumentPane Style="{DynamicResource DocumentPaneStyleMosaic}" >
<ad:DocumentContent Title="Recorded"
IsFloatingAllowed="False" IsCloseable="False">
</ad:DocumentContent>
</ad:DocumentPane>
<ad:DockablePane Style="{DynamicResource DockablePaneStyleMosaic}">
<ad:DockableContent
StateChanged="Live_StateChanged"
DockableStyle="DockableToBorders" IsCloseable="False" Title="Reports">
</ad:DockableContent>
</ad:DockablePane>
</ad:ResizingPanel>
</ad:ResizingPanel>
</ad:DockingManager>
.
There is another catch , all the edited style that we have applied on DockablePane gets removed once the DockablePane is in floating state . So once the DockablePane is dragged in floating state , all the style is lost. To get around this problem we can use StateChanged event fired by the DockablePane whenever the state is changed from Docked to floating and vice-versa.
private void Live_StateChanged(object sender,
AvalonDock.DockableContentState state)
{
try
{
AvalonDock.DockableContent panel =
sender as AvalonDock.DockableContent;
if(state == AvalonDock.DockableContentState.Docked )
{
(panel.Parent as AvalonDock.DockablePane).Style =
this.FindResource("DockablePaneStyleMosaic") as Style;
}
//Floating
if (state == AvalonDock.DockableContentState.DockableWindow )
{
(panel.Parent as AvalonDock.DockablePane).Style =
this.FindResource("DockablePaneStyleMosaic") as Style;
}
}
catch (Exception ex)
{
LogWriter.WriteLog("", ex);
}
}
As long as Avalon dock fulfills the requirement of my project , I am going to stick with it.http://avalondock.codeplex.com/
Subscribe to:
Posts (Atom)