Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-scribus-managing-colors
Packt
10 Dec 2010
7 min read
Save for later

Scribus: Managing Colors

Packt
10 Dec 2010
7 min read
  Scribus 1.3.5: Beginner's Guide Create optimum page layouts for your documents using productive tools of Scribus. Master desktop publishing with Scribus Create professional-looking documents with ease Enhance the readability of your documents using powerful layout tools of Scribus Packed with interesting examples and screenshots that show you the most important Scribus tools to create and publish your documents. Time for action – managing new colors To define your own color set, you'll need to go to Edit | Colors. Here you will have several options. The most import will be the New button, which displays a window that will give you all that you need to define your color perfectly. Give a unique and meaningful name to your color; it will help you recognize it in the color lists later. For the color model, you'll need to choose between CMYK, RGB, or Web safe RGB. If you intend to print the document, choose CMYK. If you need to put it on a website, you can choose the RGB model. Web safe, will be more restricted but you'll be sure that the chosen colors will have a similar render on every kind of monitor. Old and New show an overview of the previous state of a color when editing an existing color and the state of the actual, chosen color. It's very practical to compare. To choose your color, everything is placed on the right-hand side. You can click in the color spectrum area, drag the primary sliders, or enter the value of each primary in the field if you already know exactly which color you want. The HSV Color Map on top is the setting that gives you the spectrum. If you choose another, you'll see predefined swatches. Most of them are RGB and should not be used directly for printed documents. Click on OK to validate it in the Edit Color window and in the Colors window too. (Move the mouse over the image to enlarge.) If no document is opened, the Colors window will have some more buttons that will be very helpful. The Current Color Set should be set to Scribus Basic, which is the simplest color set. You can choose any other set but they contain RGB colors only. Then you can add your own colors, if you haven't already done so. Click on Save Color Set and give it a name. Your set will now be listed in the list and will be available for every new document. What just happened? Creating colors is very simple and can be done in few steps. In fact, creating some colors is much faster than having to choose the same color from a long, default color list. My advice would be: don't lose your time looking for a color in a predefined swatch unless you really need this color (like a Pantone or any other spot). Consider the following points: You should know the average color you need before looking for it It will take some time to take a look at all the available colors The color might not be in a predefined swatch Don't use the set everybody uses, it will help you make your document recognizable If no document is opened, the color will be added to the default swatch unless you create your own color name. If a Scribus document is open, even empty, the color will be saved in the document. Let's see how to reuse it if needed. Reusing colors from other files If you already have the colors somewhere, there might be a way to pick it without having to create it again. If the color is defined in an imported vector (mainly EPS or SVG) file, the colors will automatically be added in the color list with a name beginning with FromEPS or FromSVG followed by hexadecimal values of the color. In an EPS, colors can be CMYK or spot, but in SVG they will be RGB. CMYK between Inkscape and Scribus Inkscape colors are RGB but this software is color managed, so you can have an accurate on screen-rendering and you can add a 5-digit color-profile value to the color style property. Actually, no software adds this automatically. Doing it manually in Inkscape through the XML editor will require some knowledge of SVG and CSS. It will be easier to simply get your RGB colors and then go, after import, to the Edit | Colors window and refine the colors by clicking on the Edit button. If your color is in an imported picture or is placed somewhere else, you can use the Eye Dropper tool (the last icon of the toolbar). When you click on a color, you will be asked for a name and the color will be added as RGB in the color list. If you want to use it in CMYK, just edit the color and change the color model. The last important use case is an internal Scribus case. The color list swatch defined in a document is available only in that document and saved within it. The bad point of this is that they won't automatically be available for future documents. But the good point is that you can send your file to anyone and your colors will still be there. You have several ways of doing this. Time for action – importing from a Scribus document We have already seen how to import style and master pages from other existing Scribus documents; importing colors will be very similar. The simplest method to reuse existing already defined colors is to go to Edit | Colors. Click on the Import button. Browse your directories to find the Scribus file that contains the colors you want and select it. All the colors of this document will be added to your new document swatch. If you don't need some colors, just select them in the Edit | Colors list and click on the Delete button. Scribus will ask you which color will replace this deleted color. If this color is unused in your new document, it doesn't matter. What just happened? The Edit Colors window provides a simple way to import the colors from another Scribus document: if the colors are already set in it, you just have to choose it. But there are many other ways to do it, especially because colors are considered as frame options and can be imported with them. In fact, if you really need the same colors, you certainly won't like importing them each time you create a new document. The best you can do is create a file with your master pages, styles, and colors defined and save it as a model. Each new document will be created from this model, so you'll get them easily each time. The same will happen if you use a scrapbook. Performing those steps can help you get in few seconds everything you have already defined in another similar document. Finally, you may need to reuse those colors but not in the same kind of document. You can create a swatch in GIMP .gpl format or use any EPS or AI file. GIMP .gpl format is very simple but can be only RGB. Give the value of each RGB color. Press the Tab key and write the name of the color (for example, medium grey would be: 127 127 127 grey50). Each color has to be alone on its line. GPL, EPS, and AI files have to be placed in the Scribus swatch install directory (on Linux /usr/lib/scribus/swatches, on Macs Applications/Scribus/Contents/lib/scribus/swatches, and on Microsoft Windows Programs/scribus/lib/scribus/swatches). When using an EPS file you might get too many colors. Create as many sample shapes as needed on a page and apply a color that you want to keep on each. Then go to Edit | Colors and click on Remove Unused. Then close this window and delete the shapes. The best way will be the one you'll prefer. Test them all and maybe find your own.
Read more
  • 0
  • 0
  • 6636

article-image-getting-started-spring-python
Packt
10 Dec 2010
12 min read
Save for later

Getting started with Spring Python

Packt
10 Dec 2010
12 min read
Spring Python for Python developers You have already picked one of the most popular and technically powerful dynamic languages to develop software, Python. Spring Python makes it even easier to solve common problems encountered by Python developers every day. Exploring Spring Python's non-invasive nature Spring Python has a non-invasive nature, which means it is easy to adopt the parts that meet your needs, without rewriting huge blocks of code. For example, Pyro (http://pyro.sourceforge.net) is a 3rd party library that provides an easy way to make remote procedure calls. In order to demonstrate the Spring way of non-invasiveness, let's code a simple service, publish it as a web service using Pyro's API, and then publish it using Spring Python's wrapper around Pyro. This will show the difference in how Spring Python simplifies API access for us, and how it makes the 3rd party library easier to use without as much rework to our own code. First, let's write a simple service that parses out the parameters from a web request string: class ParamParser(object): def parse_web_parms(self, parm): return [tuple(p.split("=")) for p in parm.split("&")] Now we can write a simple, functional piece of code that uses our service in order to have a working version. parser = ParamParser() parser.parse_web_parms("pages=5&article=Spring_Python") This is just instantiating the ParamParser and accessing the function. To make this a useful internet service, it needs to be instantiated on a central server and should be configured to listen for calls from clients. The next step is to advertise it as a web service using the API of Pyro. This will make it reachable by multiple Pyro clients. To do this, we define a daemon which will host our service on port 9000 and initialize it. daemon = Pyro.core.Daemon(host="localhost", port="9000") Pyro.core.initServer() Next, we create a Pyro object instance to act as proxy to our service as well as an instance of our ParamParser. We configure the proxy to delegate all method calls to our service. pyro_proxy = Pyro.core.ObjBase() parser = ParamParser() pyro_proxy.delegateTo(parser) Finally, we register the pyro_proxy object with the daemon, and startup a listen-dispatch loop so that it's ready to handle requests: daemon.connect(pyro_proxy, "mywebservice") daemon.requestLoop(True) When we run this server code, an instance of our ParamParser will be created and advertised at PYROLOC://localhost:9000/mywebservice. To make this service complete, we need to create a Pyro client that will call into our service. The proxy seamlessly transfers Python objects over the wire using the Pyro library, in this case the tuple of request parameters. url_base = "PYROLOC://localhost:9000" client_proxy = Pyro.core.getProxyForURI( url_base + "/mywebservice") print client_proxy.parse_web_parms( "pages=5&article=Spring_Python") The Pyro library is easy to use. One key factor is how our ParamParser never gets tightly coupled to the Pyro machinery used to serve it to remote clients. However, it's very invasive. What if we had already developed a simple application on a single machine with lots of methods making use of our utility? In order to convert our application into a client-server application, we would have to rewrite it to use the Pyro client proxy pattern everywhere that it was called. If we miss any instances, we will have bugs that need to be cleaned up. If we had written automated tests, they would also have to be rewritten as well. Converting a simple, one-machine application into a multi-node application can quickly generate a lot of work. That is where Spring Python comes in. It provides a different way of creating objects which makes it easy for us to replace a local object with a remoting mechanism such as Pyro. Let's utilize Spring Python's container to create our parser and also to serve it up with Pyro. from springpython.config import PythonConfig from springpython.config import Object from springpython.remoting.pyro import PyroServiceExporter from springpython.remoting.pyro import PyroProxyFactory class WebServiceContainer(PythonConfig): def __init__(self): super(WebServiceContainer, self).__init__() @Object(lazy_init=True) def my_web_server(self): return PyroServiceExporter(service=ParamParser(), service_name="mywebservice", service_port=9000) @Object(lazy_init=True) def my_web_client(self): myService = PyroProxyFactory() myService.service_url="PYROLOC://localhost:9000/mywebservice" return myService With this container definition, it is easy to write both a server application as well as a client application. To spin up one instance of our Pyro server, we use the following code: from springpython.context import ApplicationContext container = ApplicationContext(WebServiceContainer()) container.get_object("my_web_server") The client application looks very similar. from springpython.context import ApplicationContext container = ApplicationContext(WebServiceContainer()) myService = container.get_object("my_web_client") myService.parse_web_parms("pages=5&article=Spring_Python") The Spring Python container works by containing all the definitions for creating key objects. We create an instance of the container, ask it for a specific object, and then use it. This easily looks like just as much (if not more) code than using the Pyro API directly. So why is it considered less invasive? Looking at the last block of code, we can see that we are no longer creating the parser or the Pyro proxy. Instead, we are relying on the container to create it for us. The Spring Python container decouples the creation of our parser, whether its for a local application, or if it uses Pyro to join them remotely. The server application doesn't know that it is being exported as a Pyro service, because all that information is stored in the WebServiceContainer. Any changes made to the container definition aren't seen by the server application code. The same can be said for the client. By putting creation of the client inside the container, we don't have to know whether we are getting an instance of our service or a proxy. This means that additional changes can be made inside the definition of the container of Spring Python, without impacting our client and server apps. This makes it easy to split the server and client calls into separate scripts to be run in separate instances of Python or on separate nodes in our enterprise. This demonstrates how it is possible to mix in remoting to our existing application. By using this pattern of delegating creation of key objects to the container, it is easy to start with simple object creation, and then layer on useful services such as remoting. Later in this book, we will also see how this makes it easy to add other services like transactions and security. Due to Spring Python's open ended design, we can easily create new services and add them on without having to alter the original framework. Adding in some useful templates In addition to the non-invasive ability to mix in services, Spring Python has several utilities that ease the usage of low level APIs through a template pattern. The template pattern involves capturing a logical flow of steps. What occurs at each step is customizable by the developer, while still maintaining the same overall sequence. One example where a template would be useful is for writing a SQL query. Coding SQL queries by hand using Python's database API (http://www.python.org/dev/peps/pep-0249) is very tedious. We must properly handle errors and harvest the results. The extra code involved with connecting things together and handling issues is commonly referred to as plumbing code. Let's look at the following code to see how Python's database API functions. The more plumbing code we have to maintain, the higher the cost. Having an application with dozens or hundreds of queries can become unwieldy, even cost prohibitive to maintain. Using Python's database API, we only have to write the following code once for setup. ### One time setup import MySQLdb conn = MySQLdb.connection(username="me", password"secret", hostname="localhost", db="springpython") Now let's use Python's database API to perform a single query. ### Repeated for every query cursor = conn.cursor() results = [] try: cursor.execute("""select title, air_date, episode_number, writer from tv_shows where name = %s""", ("Monty Python",)) for row in cursor.fetchall(): tvShow = TvShow(title=row[0], airDate=row[1], episodeNumber=row[2], writer=row[3]) results.append(tvShow) finally: try: cursor.close() except Exception: pass conn.close() return results   The specialized code we wrote to look up TV shows is contained in the execute statement and also the part that creates an instance of TvShow. The rest is just plumbing code needed to handle errors, manage the database cursor, and iterate over the results.   This may not look like much, but have you ever developed an application with just one SQL query? We could have dozens or even hundreds of queries, and having to repeatedly code these steps can become overwhelming. Spring Python's DatabaseTemplate lets us just inject the query string and and a row mapper to reduce the total amount of code that we need to write. We need a slightly different setup than before. """One time setup""" from springpython.database.core import * from springpython.database.factory import * connectionFactory = MySQLConnectionFactory(username="me", password="secret", hostname="localhost", db="springpython") We also need to define a mapping to generate our TvShow objects. class TvShowMapper(RowMapper): def map_row(self, row, metadata=None): return TvShow(title=row[0], airDate=row[1], episodeNumber=row[2], writer=row[3]) With all this setup, we can now create an instance of DatabaseTemplate and use it to execute the same query with a much lower footprint. dt = DatabaseTemplate(connectionFactory) """Repeated for each query""" results = dt.query("""select title, air_date, episode_number, writer from tv_shows where name = %s""", ("Monty Python",), TvShowMapper()) This example shows how we can replace 19 lines of code with a single statement using Spring Python's template solution. Object Relational Mappers (ORMs) have sprung up in response to the low level nature of ANSI SQL's protocol. Many applications have simple object persistence requirements and many of us would prefer working on code, and not database design. By having a tool to help do the schema management work, these ORMs have been a great productivity boost. But they are not necessarily the answer for every use case. Some queries are very complex and involve looking up information spread between many tables, or involve making complex calculations and involve decoding specific values. Also, many legacy systems are denormalized and don't fit the paradigm that ORMs were originally designed to handle. The complexity of these queries can require working around, or even against, the ORM-based solutions, making them not worth the effort. To alleviate the frustration of working with SQL, Spring Python's DatabaseTemplate greatly simplifies writing SQL, while giving you complete freedom in mapping the results into objects, dictionaries, and tuples. DatabaseTemplate can easily augment your application, whether or not you are already using an ORM. That way, simple object persistence can be managed with ORM, while complex queries can be handed over to Spring Python's DatabaseTemplate, resulting in a nice blend of productive, functional code. Other templates, such as TransactionTemplate, relieve you of the burden of dealing with the low level idioms needed to code transactions that makes them challenging to incorporate correctly. Later in this book, we will learn how easy it is to add transactions to our code both programmatically and declaratively. Applying the services you need and abstracting away low level APIs is a key part of the Spring way and lets us focus our time and effort on our customer's business requirements instead of our own technical ones. By using the various components we just looked at, it isn't too hard to develop a simple Pyro service that serves up TV shows from a relational database. from springpython.database.factory import * from springpython.config import * from springpython.remoting.pyro import * class TvShowMapper(RowMapper): def map_row(self, row, metadata=None): return (title=row[0], airDate=row[1], episodeNumber=row[2], writer=row[3]) class TvShowService(object): def __init__(self): self.connFactory = MySQLConnectionFactory(username="me", password="secret", hostname="localhost", db="springpython") self.dt = DatabaseTemplate(connFactory) def get_tv_shows(self): return dt.query("""select title, air_date, episode_number, writer from tv_shows where name = %s""", ("Monty Python",), TvShowMapper()) class TvShowContainer(PythonConfig): def __init__(self): super(TvShowContainer, self).__init__() @Object(lazy_init=True) def web_server(self): return PyroServiceExporter(service=TvShowService(), service_name="tvshows", service_port=9000) @Object(lazy_init=True) def web_client(self): myService = PyroProxyFactory() myService.service_url="PYROLOC://localhost:9000/tvshows" return myService if __name__ == "__main__": container = ApplicationContext(TvShowContainer()) container.get_object("web_server") By querying the database for TV shows and serving it up through Pyro, this block of code demonstrates how easy it is to use these powerful modules without mixing them together. It is much easier to maintain software over time when things are kept simple and separated. We just took a quick walk through SQL and Pyro and examined their low level APIs. Many low level APIs require a certain sequence of steps to properly utilize them. We just looked at a SQL query. The need for templates also exists with database transactions and LDAP calls. By capturing the flow of the API in a Spring Python template and allowing you to insert your custom code, you can get out of writing plumbing code and instead work on your application's business logic.
Read more
  • 0
  • 0
  • 6210

article-image-oracle-books-2010-2011
Packt
10 Dec 2010
1 min read
Save for later

Oracle Books 2010 - 2011

Packt
10 Dec 2010
1 min read
Oracle Application Express 4.0 with Ext JS: RAW Oracle GoldenGate 11g Implementor's Guide Oracle ADF Enterprise Application Development Made Simple Oracle Siebel CRM 8 Developer's Handbook: RAW RAW Oracle books are not due to be published until 2011, but are available now in RAW format, whereby you can download and access immediately, reading as they're written For further information on Packt RAW books click here For an overview of Oracle Books published in 2010 click here  
Read more
  • 0
  • 0
  • 963

article-image-plugins-cms-design
Packt
10 Dec 2010
15 min read
Save for later

Plugins in CMS Design

Packt
10 Dec 2010
15 min read
  CMS Design Using PHP and jQuery Build and improve your in-house PHP CMS by enhancing it with jQuery Create a completely functional and a professional looking CMS Add a modular architecture to your CMS and create template-driven web designs Use jQuery plugins to enhance the "feel" of your CMS A step-by-step explanatory tutorial to get your hands dirty in building your own CMS         Read more about this book       (For more resources on this subject, see here.) After completing this article, the CMS could be considered "complete", in that almost every other requested feature can be supplied by writing a plugin for it. However, it should be noted that a CMS never is actually complete, because each new website may bring a new request that is not yet catered for. Having said that, using plugins lets you at least complete a "core" engine and concentrate on providing hooks that allow further development to be done, outside that core. What are plugins A plugin is a module of code that can be dropped into a directory and enabled, to give a CMS extra capabilities. Plugins need to be able to change the output and do other tasks, so it is necessary to add various "hooks" throughout the code where the plugins can apply their code. A very important reason for adding a plugin architecture to a CMS is that it lets you stabilize the core code. The core is basically the code that will be available in every instance of the CMS, as opposed to plugin code, which may or may not be present in any particular instance of the CMS. With a core piece of code that is deemed "complete", it becomes easier to manage bugs. Because you are not always adding to the core code, you are not actively adding to the potential number of bugs. In a CMS which does not have a stable core, any change to the central code can affect just about anything else. You really need to get your CMS to a stage where you are no longer developing the central engine. Instead, you are working mostly on external plugins and maybe occasional bug fixes to the core, as they are found. In my case, for example, I worked for years on building up a CMS before getting around to building in plugins. Every change that was requested was built into the core code. Usually, only the fully-tested code at that time would be the new code, so very often we would miss a problem that the new code would have caused somewhere else in the CMS. Often, this problem would not show up for weeks, so it would not be obvious what the problem was related to! When all the development of a CMS is shifted to plugins, it becomes less likely that the core is at fault when a problem occurs. Because plugins, by their nature, tend to be isolated pieces of code, if a bug does appear, it is very likely the bug is within the plugin's code and not anywhere else. Also, because plugins allow a person to develop without touching the core engine, it is possible for the external teams or individuals to create their own plugins that they can use with the engine, without needing to understand all the parts of the core engine. One more advantage is that if the plugin architecture is solid, it is possible for development to continue on the core completely separately from the plugins, knowing that plugins from one version of the CMS will most likely work with a core from another version. Events in the CMS One example of a hook is event triggers. In JavaScript (and therefore jQuery), there is the concept of events, where you can set a block of code to run when a certain trigger happens. For example, when you move your mouse over an element, there are a number of potential trigger points—onmouseover, onmouseenter, onmousemove (and possibly others, depending on the context). Obviously, PHP does not have those events, as it's a server-side language. But it is possible to conceive of triggers for your CMS that you could potentially hook onto. For example, let's say you've just finished figuring out the page content. At this point, you may want to trigger a page-content-created event. This could (and will, in this article) be used by a Page Comments plugin to tack on the comments thread, and any required forms, to the end of that page content. Another example: Let's say you want to create a custom log for your own purposes. You would then be interested in a start trigger that can be used to initialize certain values, such as a timer. After the output has been sent, a finish trigger that can be used to tally up a number of figures (compilation time, memory used, size of rendered output, and so on) and record them in a file or database before the script finishes. Page types In some cases, you will want the page content to be totally converted. Instead of showing a page body as normal, you may want to show an image gallery or a store checkout. In this case, you would need to create a "page type" block of code, which the frontend will use instead of the usual page data render() call. In the admin area, this might also require using a customized form instead of the usual rich text editor. Admin sections The admin area may need to have new sections added by a plugin. In the Events section, we described a logging plugin. A perfect complement to that is a graphing log viewer, which would be shown as a completely new admin section and have its own entry in the admin menu. Page admin form additions You may also want to add extra forms to all the Page forms in the admin, regardless of what page type it is. For example, if you create a security plugin and want to protect various pages depending on who is viewing it, you will need to be able to choose which users or groups have access and what to display if the current user does not have full access. This requires an additional form in the Page admin. It is very difficult to describe all the possible plugin uses, and the number of triggers that may be required. The easiest way to proceed is to just adjust the engine as required. If it turns out you forgot to add an event trigger at some point, it should be a small matter to just add it in at that point without affecting the core code beyond that addition. Example plugin configuration Create a directory called /ww.plugins. Each plugin you create will be placed in a directory—one directory per plugin. For our first example, we're going to build a Page Comments plugin, which will allow visitors to your site to leave comments on your pages. On the admin side, we will need to provide methods to maintain the submitted comments per page and for the whole site. Anyway, create a directory to hold the plugin called /ww.plugins/page-comments. The CMS will expect the plugin configuration for each plugin to be in a file named plugin.php. So the configuration for the Page Comments plugin /ww.plugins/page-comments/plugin.php is as follows: <?php $plugin=array( 'name' => 'Page Comments', 'description' => 'Allow your visitors to comment on pages.', 'version' => '0', 'admin' => array( 'menu' => array( 'Communication>Page Comments' => 'comments' ) , 'page_tab' => array( 'name' => 'Comments', 'function' => 'page_comments_admin_page_tab' ) ), 'triggers' => array( 'page-content-created' => 'page_comments_show' ) ); The plugin.php files at least contain an array named $plugin, which describes the plugin. For now, let's look at what the current example says. All of these options, except the first two, are optional. First, we define a name, "Page Comments". This is only ever used in the admin area, when you are choosing your plugins. The same is true of the description field. The version field is used by the CMS to tell whether a plugin is up-to-date or if some automatic maintenance is needed. This will be explained in more detail later in this article. Next, we have the admin array, which holds details of the admin-only functions. The menu array is used to edit the admin menu, in case you need to add an admin section for the plugin. In this case, we will add an admin section for Page Comments, which will let you set site-wide settings and view comments site-wide. If a new tab is to be added to the page admin section, this tab is described in the page_tab array. name is what appears in the tab header, and function is the name of a PHP function that will be called to generate the tab content. Finally, the triggers array holds details of the various triggers that the plugin should react to. Each trigger calls a function. Obviously, this is not a complete list, and it is not possible to ever have a complete list, as each new circumstance you are requested to write for may bring up a need for a trigger or plugin config setting that you had not thought of. However, there are less and less additions, as the plugin architecture becomes more complete. From the plugin configuration, you can see that there are some functions named, which we have not defined. You should define those functions in the same file: function page_comments_admin_page_tab($PAGEDATA){ require_once SCRIPTBASE.'ww.plugins/page-comments/' .'admin/page-tab.php'; return $html; } function page_comments_show($PAGEDATA){ if(isset($PARENTDATA->vars->comments_disabled) && $PARENTDATA->vars->comments_disabled=='yes') return; require_once SCRIPTBASE.'ww.plugins/page-comments/' .'frontend/show.php'; } The functions are prefixed with an identifier to make sure that they don't clash with the functions from other plugins. In this case, because the plugin is named Page Comments, the prefix is page_comments_. The functions here are essentially stubs. Plugins will be loaded every time any request is made to the server. Because of this, and the obvious fact that not all the functions would be needed in every request, it makes sense to keep as little code in it as possible in the plugin.php files. In most cases, triggers will be called with just the $PAGEDATA object as a parameter. Obviously, in cases in the admin area where you're not editing any particular page this would not make sense, but for most plugins, to keep the function calls consistent, the only parameter is $PAGEDATA. Enabling plugins We have defined a plugin. We could make it such that when you place a plugin in the /ww.plugins directory, it is automatically enabled. However, if you are creating a CMS that you intend to reuse for a lot of other clients, it is a lot easier to simply copy the entire CMS source and reconfigure, than to copy the CMS source and then clear out the existing plugins and repopulate carefully with new ones that you would download from a repository that you keep somewhere else. So, what we do is we give the admin a maintenance page where they choose the plugins they want to load. The CMS then only loads those and does not even look at the other directories. Edit the /ww.admin/header.php file and add a new link (highlighted) to the plugin admin section: <a href="/ww.admin/themes.php">Themes</a>     Plugins     Log Out   We will be changing the admin menu later in this article to make it customizable more easily, but for now, add in that link manually. Now create the /ww.admin/plugins.php file: <?php require 'header.php'; echo ' Plugin Management '; echo ' '; echo 'Users'; echo 'Themes'; echo 'Plugins'; echo ' '; echo ' '; echo ' Plugin Management '; require 'plugins/list.php'; echo ' '; require 'footer.php'; You'll have noticed that this is similar to the /ww.admin/themes.php and /ww.admin/users.php files. They're all related to site-wide settings, so I've placed links to them all in the left-menu. Edit those files and add in the new Plugins link to their menus. Before we create the page for listing the enabled plugins, we must first set up the array of enabled plugins in /ww.incs/basics.php, by adding this to the end of the file: // { plugins $PLUGINS=array(); if (isset($DBVARS['plugins'])&&$DBVARS['plugins']) { $DBVARS['plugins']=explode(',',$DBVARS['plugins']); foreach($DBVARS['plugins'] as $pname){ if (strpos('/',$pname)!==false) continue; require SCRIPTBASE . 'ww.plugins/'.$pname.'/plugin.php'; $PLUGINS[$pname]=$plugin; } } else $DBVARS['plugins']=array(); // } As you can see, we are again referencing the $DBVARS array in the /.private/config.php. Because we already have a function for editing that, all we need to do to change the list of enabled or disabled plugins, and create and maintain the $DBVARS['plugins'] array, making sure to resave the config file after each change. What the code block does is that it reads in the plugin.php file for each enabled plugin, and saves the $plugin array from each file into a global $PLUGINS array. The $DBVARS['plugins'] variable is an array, but we'll store it as a comma-delimited string in the config file. Edit config_rewrite() in the same file and add this highlighted line: $tmparr=$DBVARS; $tmparr['plugins']=join(',',$DBVARS['plugins']); $tmparr2=array(); We'll enhance the plugin loader in a short while. In the meantime, let's finish the admin plugin maintenance page. Create the directory /ww.admin/plugins, and in it, add /ww.admin/plugins/list.php: <?php echo ' '; echo ' '; // { list enabled plugins first foreach($PLUGINS as $name=>$plugin){ echo '', '', '', ''; } // } // { then list disabled plugins $dir=new DirectoryIterator(SCRIPTBASE . 'ww.plugins'); foreach($dir as $plugin){ if($plugin->isDot())continue; $name=$plugin->getFilename(); if(isset($PLUGINS[$name]))continue; require_once(SCRIPTBASE.'ww.plugins/'.$name.'/plugin.php'); echo '', '', '', '', ''; } // } echo ' Plugin Name Description ',htmlspecialchars(@$plugin['name']),' ',htmlspecialchars(@$plugin['description']),' disable ',htmlspecialchars($plugin['name']),' ',htmlspecialchars($plugin['description']),' enable '; When viewed in a browser, it displays like this: The script displays a list of already-enabled plugins (we have none so far), and then reads the /ww.plugins directory for any other plugins and adds them along with an "enable" link. Now we need to write some code to do the actual selection/enabling of the plugins. While it would be great to write some jQuery to do it in an Ajaxy way (so you click on the enable link and the plugin is enabled in the background, without reloading the page), there are too many things that might cause problems. For instance, if the plugin caused new items to appear in the menu, we'd have to handle that. If the plugin changed the theme, or did anything else that caused a layout change, we'd have to handle that as well. So instead, we'll do it the old-fashioned PHP way—you click on enable or disable, which does the job on the server, and then reloads the plugin page so you can see the change. Create the /ww.admin/plugins/enable.php file: <?php require '../admin_libs.php'; if(!in_array($_REQUEST['n'],$DBVARS['plugins'])){ $DBVARS['plugins'][]=$_REQUEST['n']; config_rewrite(); } header('Location: /ww.admin/plugins.php'); It simply adds the requested plugin to the $DBVARS['plugins'] array, then rewrites the config and redirects the browser back to the plugins page. When clicked, the page apparently just reloads, and the plugin's link changes to disable. The opposite script is just as simple. Write this code block in the file /ww.admin/plugins/disable.php: <?php require '../admin_libs.php'; if(in_array($_REQUEST['n'],$DBVARS['plugins'])){ unset($DBVARS['plugins'][ array_search($_REQUEST['n'],$DBVARS['plugins']) ]); config_rewrite(); } header('Location: /ww.admin/plugins.php'); In this case, all we needed to do was to remove the plugin name from $DBVARS['plugins'] by unsetting its position in the array. Plugins are now very simply set up. Here's a screenshot of that page with a number of plugins enabled and disabled. I copied some plugins from a more mature copy of the CMS that I have. We will be looking at a few of them, and building one or two others: The enabled plugins are moved to the top of the list to make them more visible and the rest are shown below them.
Read more
  • 0
  • 0
  • 1571

article-image-python-multimedia-video-format-conversion-manipulations-and-effects
Packt
10 Dec 2010
11 min read
Save for later

Python Multimedia: Video Format Conversion, Manipulations and Effects

Packt
10 Dec 2010
11 min read
  Python Multimedia Learn how to develop Multimedia applications using Python with this practical step-by-step guide Use Python Imaging Library for digital image processing. Create exciting 2D cartoon characters using Pyglet multimedia framework Create GUI-based audio and video players using QT Phonon framework. Get to grips with the primer on GStreamer multimedia framework and use this API for audio and video processing.       Installation prerequisites We will use Python bindings of GStreamer multimedia framework to process video data. See Python Multimedia: Working with Audios for the installation instructions to install GStreamer and other dependencies. For video processing, we will be using several GStreamer plugins not introduced earlier. Make sure that these plugins are available in your GStreamer installation by running the gst-inspect-0.10 command from the console (gst-inspect-0.10.exe for Windows XP users). Otherwise, you will need to install these plugins or use an alternative if available. Following is a list of additional plugins we will use in this article: autoconvert: Determines an appropriate converter based on the capabilities. It will be used extensively used throughout this article. autovideosink: Automatically selects a video sink to display a streaming video. ffmpegcolorspace: Transforms the color space into a color space format that can be displayed by the video sink. capsfilter: It's the capabilities filter—used to restrict the type of media data passing down stream, discussed extensively in this article. textoverlay: Overlays a text string on the streaming video. timeoverlay: Adds a timestamp on top of the video buffer. clockoverlay: Puts current clock time on the streaming video. videobalance: Used to adjust brightness, contrast, and saturation of the images. It is used in the Video manipulations and effects section. videobox: Crops the video frames by specified number of pixels—used in the Cropping section. ffmux_mp4: Provides muxer element for MP4 video muxing. ffenc_mpeg4: Encodes data into MPEG4 format. ffenc_png: Encodes data in PNG format. Playing a video Earlier, we saw how to play an audio. Like audio, there are different ways in which a video can be streamed. The simplest of these methods is to use the playbin plugin. Another method is to go by the basics, where we create a conventional pipeline and create and link the required pipeline elements. If we only want to play the 'video' track of a video file, then the latter technique is very similar to the one illustrated for audio playback. However, almost always, one would like to hear the audio track for the video being streamed. There is additional work involved to accomplish this. The following diagram is a representative GStreamer pipeline that shows how the data flows in case of a video playback. In this illustration, the decodebin uses an appropriate decoder to decode the media data from the source element. Depending on the type of data (audio or video), it is then further streamed to the audio or video processing elements through the queue elements. The two queue elements, queue1 and queue2, act as media data buffer for audio and video data respectively. When the queue elements are added and linked in the pipeline, the thread creation within the pipeline is handled internally by the GStreamer. Time for action – video player! Let's write a simple video player utility. Here we will not use the playbin plugin. The use of playbin will be illustrated in a later sub-section. We will develop this utility by constructing a GStreamer pipeline. The key here is to use the queue as a data buffer. The audio and video data needs to be directed so that this 'flows' through audio or video processing sections of the pipeline respectively. Download the file PlayingVidio.py from the Packt website. The file has the source code for this video player utility. The following code gives an overview of the Video player class and its methods. import time import thread import gobject import pygst pygst.require("0.10") import gst import os class VideoPlayer: def __init__(self): pass def constructPipeline(self): pass def connectSignals(self): pass def decodebin_pad_added(self, decodebin, pad): pass def play(self): pass def message_handler(self, bus, message): pass # Run the program player = VideoPlayer() thread.start_new_thread(player.play, ()) gobject.threads_init() evt_loop = gobject.MainLoop() evt_loop.run() As you can see, the overall structure of the code and the main program execution code remains the same as in the audio processing examples. The thread module is used to create a new thread for playing the video. The method VideoPlayer.play is sent on this thread. The gobject.threads_init() is an initialization function for facilitating the use of Python threading within the gobject modules. The main event loop for executing this program is created using gobject and this loop is started by the call evt_loop.run(). Instead of using thread module you can make use of threading module as well. The code to use it will be something like: import threading threading.Thread(target=player.play).start() You will need to replace the line thread.start_new_thread(player.play, ()) in earlier code snippet with line 2 illustrated in the code snippet within this note. Try it yourself! Now let's discuss a few of the important methods, starting with self.contructPipeline: 1 def constructPipeline(self): 2 # Create the pipeline instance 3 self.player = gst.Pipeline() 4 5 # Define pipeline elements 6 self.filesrc = gst.element_factory_make("filesrc") 7 self.filesrc.set_property("location", 8 self.inFileLocation) 9 self.decodebin = gst.element_factory_make("decodebin") 10 11 # audioconvert for audio processing pipeline 12 self.audioconvert = gst.element_factory_make( 13 "audioconvert") 14 # Autoconvert element for video processing 15 self.autoconvert = gst.element_factory_make( 16 "autoconvert") 17 self.audiosink = gst.element_factory_make( 18 "autoaudiosink") 19 20 self.videosink = gst.element_factory_make( 21 "autovideosink") 22 23 # As a precaution add videio capability filter 24 # in the video processing pipeline. 25 videocap = gst.Caps("video/x-raw-yuv") 26 self.filter = gst.element_factory_make("capsfilter") 27 self.filter.set_property("caps", videocap) 28 # Converts the video from one colorspace to another 29 self.colorSpace = gst.element_factory_make( 30 "ffmpegcolorspace") 31 32 self.videoQueue = gst.element_factory_make("queue") 33 self.audioQueue = gst.element_factory_make("queue") 34 35 # Add elements to the pipeline 36 self.player.add(self.filesrc, 37 self.decodebin, 38 self.autoconvert, 39 self.audioconvert, 40 self.videoQueue, 41 self.audioQueue, 42 self.filter, 43 self.colorSpace, 44 self.audiosink, 45 self.videosink) 46 47 # Link elements in the pipeline. 48 gst.element_link_many(self.filesrc, self.decodebin) 49 50 gst.element_link_many(self.videoQueue, self.autoconvert, 51 self.filter, self.colorSpace, 52 self.videosink) 53 54 gst.element_link_many(self.audioQueue,self.audioconvert, 55 self.audiosink) In various audio processing applications, we have used several of the elements defined in this method. First, the pipeline object, self.player, is created. The self.filesrc element specifies the input video file. This element is connected to a decodebin. On line 15, autoconvert element is created. It is a GStreamer bin that automatically selects a converter based on the capabilities (caps). It translates the decoded data coming out of the decodebin in a format playable by the video device. Note that before reaching the video sink, this data travels through a capsfilter and ffmpegcolorspace converter. The capsfilter element is defined on line 26. It is a filter that restricts the allowed capabilities, that is, the type of media data that will pass through it. In this case, the videoCap object defined on line 25 instructs the filter to only allow video-xraw-yuv capabilities. The ffmpegcolorspace is a plugin that has the ability to convert video frames to a different color space format. At this time, it is necessary to explain what a color space is. A variety of colors can be created by use of basic colors. Such colors form, what we call, a color space. A common example is an rgb color space where a range of colors can be created using a combination of red, green, and blue colors. The color space conversion is a representation of a video frame or an image from one color space into the other. The conversion is done in such a way that the converted video frame or image is a closer representation of the original one. The video can be streamed even without using the combination of capsfilter and the ffmpegcolorspace. However, the video may appear distorted. So it is recommended to use capsfilter and ffmpegcolorspace converter. Try linking the autoconvert element directly to the autovideosink to see if it makes any difference. Notice that we have created two sinks, one for audio output and the other for the video. The two queue elements are created on lines 32 and 33. As mentioned earlier, these act as media data buffers and are used to send the data to audio and video processing portions of the GStreamer pipeline. The code block 35-45 adds all the required elements to the pipeline. Next, the various elements in the pipeline are linked. As we already know, the decodebin is a plugin that determines the right type of decoder to use. This element uses dynamic pads. While developing audio processing utilities, we connected the pad-added signal from decodebin to a method decodebin_pad_added. We will do the same thing here; however, the contents of this method will be different. We will discuss that later. On lines 50-52, the video processing portion of the pipeline is linked. The self.videoQueue receives the video data from the decodebin. It is linked to an autoconvert element discussed earlier. The capsfilter allows only video-xraw-yuv data to stream further. The capsfilter is linked to a ffmpegcolorspace element, which converts the data into a different color space. Finally, the data is streamed to the videosink, which, in this case, is an autovideosink element. This enables the 'viewing' of the input video. Now we will review the decodebin_pad_added method. 1 def decodebin_pad_added(self, decodebin, pad): 2 compatible_pad = None 3 caps = pad.get_caps() 4 name = caps[0].get_name() 5 print "n cap name is =%s"%name 6 if name[:5] == 'video': 7 compatible_pad = ( 8 self.videoQueue.get_compatible_pad(pad, caps) ) 9 elif name[:5] == 'audio': 10 compatible_pad = ( 11 self.audioQueue.get_compatible_pad(pad, caps) ) 12 13 if compatible_pad: 14 pad.link(compatible_pad) This method captures the pad-added signal, emitted when the decodebin creates a dynamic pad. Here the media data can either represent an audio or video data. Thus, when a dynamic pad is created on the decodebin, we must check what caps this pad has. The name of the get_name method of caps object returns the type of media data handled. For example, the name can be of the form video/x-raw-rgb when it is a video data or audio/x-raw-int for audio data. We just check the first five characters to see if it is video or audio media type. This is done by the code block 4-11 in the code snippet. The decodebin pad with video media type is linked with the compatible pad on self.videoQueue element. Similarly, the pad with audio caps is linked with the one on self.audioQueue. Review the rest of the code from the PlayingVideo.py. Make sure you specify an appropriate video file path for the variable self.inFileLocation and then run this program from the command prompt as: $python PlayingVideo.py This should open a GUI window where the video will be streamed. The audio output will be synchronized with the playing video. What just happened? We created a command-line video player utility. We learned how to create a GStreamer pipeline that can play synchronized audio and video streams. It explained how the queue element can be used to process the audio and video data in a pipeline. In this example, the use of GStreamer plugins such as capsfilter and ffmpegcolorspace was illustrated. The knowledge gained in this section will be applied in the upcoming sections in this article. Playing video using 'playbin' The goal of the previous section was to introduce you to the fundamental method of processing input video streams. We will use that method one way or another in the future discussions. If just video playback is all that you want, then the simplest way to accomplish this is by means of playbin plugin. The video can be played just by replacing the VideoPlayer.constructPipeline method in file PlayingVideo.py with the following code. Here, self.player is a playbin element. The uri property of playbin is set as the input video file path. def constructPipeline(self): self.player = gst.element_factory_make("playbin") self.player.set_property("uri", "file:///" + self.inFileLocation)
Read more
  • 0
  • 0
  • 8114

article-image-working-colors-scribus
Packt
10 Dec 2010
10 min read
Save for later

Working with Colors in Scribus

Packt
10 Dec 2010
10 min read
Scribus 1.3.5: Beginner's Guide Create optimum page layouts for your documents using productive tools of Scribus. Master desktop publishing with Scribus Create professional-looking documents with ease Enhance the readability of your documents using powerful layout tools of Scribus Packed with interesting examples and screenshots that show you the most important Scribus tools to create and publish your documents. Applying colors in Scribus Applying color is as basic as creating a frame or writing text. In this article we will often give color values. Each time we need to, we will use the first letter of the color followed by its value. For example, C75 will mean 75 percent of cyan. K will be used for black and B for blue. There are five main things you could apply colors to: Frame or Shape fill Frame or Shape border Line Text Text border You'd like to colorize pictures too. It's a very different method, using duotone or any equivalent image effect. Applying a color to a frame means that you will use the Colors tab of the PP, whereas applying color to text will require you to go to the Color & Effects expander in the Text tab. In both cases you'll find what's needed to apply color to the fill and the border, but the user interfaces are a bit different. (Move the mouse over the image to enlarge.) Time for action – applying colors to a Text Frame's text Colors on frames will use the same color list. Let's follow some steps to see how this is done. Draw a Text Frame where you want it on a page. Type some text inside like "colors of the world" or use Insert | Sample Text. Go to the Colors tab of the PP (F2). Click on the second button placed above the color list to specify that you want to apply the changes to the fill. Then click on the color you want in the list below, for example, Magenta. Click on the paintbrush button, and apply a black color that will be applied to the border (we could call it stroke too). Don't forget that applying a stroke color will need some border refinements in the Line tab to set the width and style of the border. If you need more information about these options. Now, you can select the text or some part of it and go to the Colors & Effects expander of the Text tab. Here you will again see the same icon we used previously. Each has its own color list. Let's choose Yellow for the text color. The stroke color cannot be changed. To change this, click on the Shadow button placed below, and now choose black as the stroke color. The text shadow should be black. What just happened? Color on text is quicker than frame colors in some ways because each has its own list. So, there is no need to click on any button, and you can see both at a glance. Just remember that text has no stroke color activated when setting it first. You need to add the stroke or shadow to a selection to activate the border color for that selection. Quick apply in story editor If, like me, you like the Story Editor (Edit | Edit Text), notice that colors can be applied from there. They are not displayed in the editor but will be displayed when the changes will be applied to the layout. This is much faster, but you need to know exactly what you're doing and need to be precise in your selection. If you need to apply the same color setting to a word in the overall document, you can alternatively use the Edit | Search/Replace window. You can set there the word you're looking for in the first field, and in the right-hand side, replace with the same word, and choose the Fill and Stroke color that you want to apply. Of course, it would be nice if this window could let us apply character styles to make future changes easier. The Scribus new document receives a default color list, which is the same all over your document. In this article, we will deal with many ways of adapting existing colors or creating new ones. Applying shade or transparency Shade and transparency are two ways of setting more precisely how a specific color will be applied on your items. Shades and transparencies are fake effects that will be interpreted by some later elements of the printing workflow, such as Raster Image Processors, to know how the set color can be rendered with pure colors. This is the key point of reproducing colors: if you want a gray, you'll generally have a black color for that. In offset printing which is the reference, the size of the point will vary relatively to the darkness of the black you chose. This will be optically interpreted by the reader. Using shades Each color property has a Shade value. The default is set to 100 percent, meaning that the color will be printed fully saturated. Reducing the shade value will produce a lighter color. When at 0 percent, the color, whatever it may be, will be interpreted as white. On a pure color item like any primary or spot, changing the shade won't affect the color composition. However, on processed colors that are made by mixing several primary colors, modifying the shade will proportionally change the amount of each ink used in the process. Our C75 M49 Y7 K12 at a 50 percent shade value will become a C37 M25 Y4 K6 color in the final PDF. Less color means less ink on the paper and more white (or paper color), which results in a lighter color. You should remember that Shade is a frame property and not a color property. So, if you apply a new color to the frame, the shade value will be kept and applied immediately. To change the shade of the color applied to some characters, it will be a bit different: we don't have a field to fill but a drop-down list with predefined values of 10 percent increments. If you need another value, just choose Other to display a window in which you'll add the amount that you exactly need. You can do the same in the Text Editor. Using transparency While shade is used to lighten a color, the Opacity value will tell you how the color will be less solid. Once again, the range goes from 0%, meaning the object is completely transparent and invisible, to 100% to make it opaque. The latter value is the default. When two objects overlap, the top object hides the bottom object. But when Opacity is decreased, the object at the bottom will become more and more visible. One difference to notice is that Opacity won't affect only the color rendering but the content too (if there is some). As for Shade, Opacity too is applied separately to the fill and to the stroke. So you'll need to set both if needed. One important aspect is that Shade and Opacity can both be applied on the frame and a value 50% of each will give a lighter color than if only one was used. Several opacity values applied to objects show how they can act and add to each other: The background for the text in the title, in the following screenshot, is done in the same color as the background at the top of the page. Using transparency or shade can help create this background and decrease the number of used colors. Time for action – transparency and layers Let's now use transparency and layers to create some custom effects over a picture, as can often be done for covers. Create a new document and display the Layers window from the Windows menu. This window will already contain a line called Background. You can add a layer by clicking on the + button at the bottom left-hand side of the window: it will be called New Layer 1. You can rename it by double-clicking on its name. On the first page of it, add an Image Frame that covers the entire page. Then draw a rectangular shape that covers almost half of the page height. Duplicate this layer by clicking on the middle button placed at the bottom of the Layers window. Select the visibility checkbox (it is the first column headed with an eye icon) of this layer to hide it. We'll modify the transparency of each object. Click on New Layer 1 to specify that you want to work on this layer; otherwise you won't be able to select its frames. The frames or shapes you'll create from now on will be added to this layer called New Layer 1. Select the black shape and decrease the Opacity value of the Colors tab of the PP to 50%. Do the same for the Image Frame. Now, hide this layer by clicking on its visibility icon and show the top layer. In the Layers window, verify if this layer is selected and decrease its opacity. What just happened? If there is a need to make several objects transparent at once, an idea would be to put them on a layer and set the layer Opacity. This way, the same amount of transparency will be applied to the whole. You can open the Layer window from the Window menu. When working with layers, it's important to have the right layer selected to work on it. Basically, any new layer will be added at the top of the stack and will be activated once created. When a layer is selected, you can change the Opacity of this layer by using the field on the top right-hand side of the Layer window. Since it is applied to the layer itself, all the objects placed on it will be affected, but their own opacity values won't be changed. If you look at the differences between the two layers we have made, you'll see that the area in the first black rectangle explicitly becomes transparent by itself because you can see the photo through it. This is not seen in the second. So using layer, as we have seen, can help us work faster when we need to apply the same opacity setting to several objects, but we have to take care, because the result is slightly different. Using layers to blend colors More rarely, layers can be used to mix colors. Blend Mode is originally set to Normal, which does no blending. But if you use any other mode on a layer, its colors will be mixed with colors of the item placed on a lower layer, relatively to the chosen mode. This can be very creative. If you need a more precise action, Blend Mode can be set to Single Object from the Colors tab of the PP. Just give it a try. Layers are still most commonly used to organize a document: a layer for text, a layer for images, a layer for each language for a multi-lingual document, and so on. They are a smart way to work, but are not necessary in your documents and really we can work without them in a layout program.
Read more
  • 0
  • 0
  • 14925
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-microsoft-enterprise-library-authorization-and-security-cache
Packt
09 Dec 2010
6 min read
Save for later

Microsoft Enterprise Library: Authorization and Security Cache

Packt
09 Dec 2010
6 min read
  Microsoft Enterprise Library 5.0 Develop Enterprise applications using reusable software components of Microsoft Enterprise Library 5.0 Develop Enterprise Applications using the Enterprise Library Application Blocks Set up the initial infrastructure configuration of the Application Blocks using the configuration editor A step-by-step tutorial to gradually configure each Application Block and implement its functions to develop the required Enterprise Application           Read more about this book       (For more resources on Microsoft Enterprise Library, see here.) Understanding Authorization Providers An Authorization Provider is simply a class that provides authorization logic; technically it implements either an IAuthorizationProvider interface or an abstract class named AuthorizationProvider and provides authorization logic in the Authorize method. As mentioned previously, the Security Application Block provides two Authorization Providers out of the box, AuthorizationRuleProvider and AzManAuthorizationProvider both implementing the abstract class AuthorizationProvider available in the Microsoft.Practices.EnterpriseLibrary.Security namespace. This abstract class in turn implements the IAuthorizationProvider interface, which defines the basic functionality of an Authorization Provider; it exposes a single method named Authorize, which accepts an instance of the IPrincipal object and the name of the rule to evaluate. Custom providers can be implemented either by implementing the IAuthorizationProvider interface or an abstract class named AuthorizationProvider. An IPrincipal instance (GenericPrincipal, WindowsPrincipal, PassportPrincipal, and so on) represents the security context of the user on whose behalf the code is running; it also includes the user's identity represented as an instance of IIdentity (GenericIdentity, FormsIdentity, WindowsIdentity, PassportIdentity, and so on). The following diagram shows the members and inheritance hierarchy of the respective class and interface: Authorization Rule Provider The AuthorizationRuleProvider class is an implementation that evaluates Boolean expressions to determine whether the objects are authorized; these expressions or rules are stored in the configuration file. We can create authorization rules using the Rule Expression Editor part of the Enterprise Library configuration tool and validate them using the Authorize method of the Authorization Provider. This authorization provider is part of the Microsoft.Practices.EnterpriseLibrary.Security namespace. Authorizing using Authorization Rule Provider Authorization Rule Provider stores authorization rules in the configuration and this is one of the simplest ways to perform authorization. Basically, we need to configure to use the Authorization Rule Provider and provide authorization rules based on which the authorization will be performed. Let us add Authorization Rule Provider as our Authorization Provider; click on the plus symbol on the right side of the Authorization Providers and navigate to the Add Authorization Rule Provider menu item. The following screenshot shows the configuration options of the Add Authorization Rule Provider menu item: The following screenshot shows the default configuration of the newly added Authorization Provider; in this case, it is Authorization Rule Provider: Now we have the Authorization Rule Provider added to the configuration but we still need to add the authorization rules. Imagine that we have a business scenario where: We have to allow only users belonging to the administrator's role to add or delete products. We should allow all authenticated customers to view the products. This scenario is quite common where certain operations can be performed only by specific roles, basically role-based authorization. To fulfill this requirement, we will have to add three different rules for add, delete, and view operations. Right-click on the Authorization Rule Provider and click on the Add Authorization Rule menu item as shown on the following screenshot. The following screenshot shows the newly added Authorization Rule: Let us update the name of the rule to "Product.Add" to represent the operation for which the rule is configured. We will provide the rule using the Rule Expression Editor; click on the right corner button to open the Rule Expression Editor. The requirement is to allow only the administrator role to perform this action. The following action needs to be performed to configure the rule: Click on the Role button to add the Role expression: R. Enter the role name next to the role expression: R:Admin. Select the checkbox Is Authenticated to allow only authenticated users. The following screenshot displays the Rule Expression Editor dialog box with the expression configured to R:Admin. The following screenshot shows the Rule Expression property set to R:Admin. Now let us add the rule for the product delete operation. This rule is configured in a similar fashion. The resulting configuration will be similar to the configuration shown. The following screenshot displays the added authorization rule named Product.Delete with the configured Rule Expression: Alright, we now have to allow all authenticated customers to view the products. Basically we want the authorization to pass if the user is either of role Customer; also Admin role should have permission, only then the user will be able to view products. We will add another rule called Product.View and configure the rule expression using the Rule Expression Editor as given next. While configuring the rule, use the OR operator to specify that either Admin or Customer can perform this operation. The following screenshot displays the added authorization rule named Product.View with the configured Rule Expression: Now that we have the configuration ready, let us get our hands dirty with some code. Before authorizing we need to authenticate the user; based on the authentication requirement we could be using either out-of-the-box authentication mechanism or we might use custom authentication. Assuming that we are using the current Windows identity, the following steps will allow us to authorize specific operations by passing the Windows principal while invoking the Authorize method of the Authorization Provider. The first step is to get the IIdentity and IPrincipal based on the authentication mechanism. We are using current Windows identity for this sample. WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();WindowsPrincipal windowsPrincipal = new WindowsPrincipal(windowsIdentity); Create an instance of the configured Authorization Provider using the AuthorizationFactory.GetAuthorizationProvider method; in our case we will get an instance of Authorization Rule Provider. IAuthorizationProvider authzProvider = AuthorizationFactory.GetAuthorizationProvider("Authorization Rule Provider"); Now use the instance of Authorization Provider to authorize the operation by passing the IPrincipal instance and the rule name. bool result = authzProvider.Authorize(windowsPrincipal, "Product.Add"); AuthorizationFactory.GetAuthorizationProvider also has an overloaded alternative without any parameter, which gets the default authorization provider configured in the configuration. AzMan Authorization Provider The AzManAuthorizationProvider class provides us the ability to define individual operations of an application, which then can be grouped together to form a task. Each individual operation or task can then be assigned roles to perform those operations or tasks. The best part of Authorization Manager is that it provides an administration tool as a Microsoft Management Console (MMC) snap-in to manage users, roles, operations, and tasks. Policy administrators can configure an Authorization Manager Policy store in an Active Directory, Active Directory Application Mode (ADAM) store, or in an XML file. This authorization provider is part of the Microsoft.Practices.EnterpriseLibrary.Security namespace.
Read more
  • 0
  • 0
  • 2633

article-image-wxpython-design-approaches-and-techniques
Packt
09 Dec 2010
11 min read
Save for later

wxPython: Design Approaches and Techniques

Packt
09 Dec 2010
11 min read
wxPython 2.8 Application Development Cookbook Over 80 practical recipes for developing feature-rich applications using wxPython Develop flexible applications in wxPython. Create interface translatable applications that will run on Windows, Macintosh OSX, Linux, and other UNIX like environments. Learn basic and advanced user interface controls. Packed with practical, hands-on cookbook recipes and plenty of example code, illustrating the techniques to develop feature rich applications using wxPython.     Introduction Programming is all about patterns. There are patterns at every level, from the programming language itself, to the toolkit, to the application. Being able to discern and choose the optimal approach to use to solve the problem at hand can at times be a difficult task. The more patterns you know, the bigger your toolbox, and the easier it will become to be able to choose the right tool for the job. Different programming languages and toolkits often lend themselves to certain patterns and approaches to problem solving. The Python programming language and wxPython are no different, so let's jump in and take a look at how to apply some common design approaches and techniques to wxPython applications. Creating Singletons In object oriented programming, the Singleton pattern is a fairly simple concept of only allowing exactly one instance of a given object to exist at a given time. This means that it only allows for only one instance of the object to be in memory at any given time, so that all references to the object are shared throughout the application. Singletons are often used to maintain a global state in an application since all occurrences of one in an application reference the same exact instance of the object. Within the core wxPython library, there are a number of singleton objects, such as ArtProvider , ColourDatabase , and SystemSettings . This recipe shows how to make a singleton Dialog class, which can be useful for creating non-modal dialogs that should only have a single instance present at a given time, such as a settings dialog or a special tool window. How to do it... To get started, we will define a metaclass that can be reused on any class that needs to be turned into a singleton. We will get into more detail later in the How it works section. A metaclass is a class that creates a class. It is passed a class to it's __init__ and __call__ methods when someone tries to create an instance of the class. class Singleton(type): def __init__(cls, name, bases, dict): super(Singleton, cls).__init__(name, bases, dict) cls.instance = None def __call__(cls, *args, **kw): if not cls.instance: # Not created or has been Destroyed obj = super(Singleton, cls).__call__(*args, **kw) cls.instance = obj cls.instance.SetupWindow() return cls.instance Here we have an example of the use of our metaclass, which shows how easy it is to turn the following class into a singleton class by simply assigning the Singleton class as the __metaclass__ of SingletonDialog. The only other requirement is to define the SetupWindow method that the Singleton metaclass uses as an initialization hook to set up the window the first time an instance of the class is created. Note that in Python 3+ the __metaclass__ attribute has been replaced with a metaclass keyword argument in the class definition. class SingletonDialog(wx.Dialog): __metaclass__ = Singleton def SetupWindow(self): """Hook method for initializing window""" self.field = wx.TextCtrl(self) self.check = wx.CheckBox(self, label="Enable Foo") # Layout vsizer = wx.BoxSizer(wx.VERTICAL) label = wx.StaticText(self, label="FooBar") hsizer = wx.BoxSizer(wx.HORIZONTAL) hsizer.AddMany([(label, 0, wx.ALIGN_CENTER_VERTICAL), ((5, 5), 0), (self.field, 0, wx.EXPAND)]) btnsz = self.CreateButtonSizer(wx.OK) vsizer.AddMany([(hsizer, 0, wx.ALL|wx.EXPAND, 10), (self.check, 0, wx.ALL, 10), (btnsz, 0, wx.EXPAND|wx.ALL, 10)]) self.SetSizer(vsizer) self.SetInitialSize() How it works... There are a number of ways to implement a Singleton in Python. In this recipe, we used a metaclass to accomplish the task. This is a nicely contained and easily reusable pattern to accomplish this task. The Singleton class that we defined can be used by any class that has a SetupWindow method defined for it. So now that we have done it, let's take a quick look at how a singleton works. The Singleton metaclass dynamically creates and adds a class variable called instance to the passed in class. So just to get a picture of what is going on, the metaclass would generate the following code in our example: class SingletonDialog(wx.Dialog): instance = None Then the first time the metaclass's __call__ method is invoked, it will then assign the instance of the class object returned by the super class's __call__ method, which in this recipe is an instance of our SingletonDialog. So basically, it is the equivalent of the following: SingletonDialog.instance = SingletonDialog(*args,**kwargs) Any subsequent initializations will cause the previously-created one to be returned, instead of creating a new one since the class definition maintains the lifetime of the object and not an individual reference created in the user code. Our SingletonDialog class is a very simple Dialog that has TextCtrl, CheckBox, and Ok Button objects on it. Instead of invoking initialization in the dialog's __init__ method, we instead defined an interface method called SetupWindow that will be called by the Singleton metaclass when the object is initially created. In this method, we just perform a simple layout of our controls in the dialog. If you run the sample application that accompanies this topic, you can see that no matter how many times the show dialog button is clicked, it will only cause the existing instance of the dialog to be brought to the front. Also, if you make changes in the dialog's TextCtrl or CheckBox, and then close and reopen the dialog, the changes will be retained since the same instance of the dialog will be re-shown instead of creating a new one. Implementing an observer pattern The observer pattern is a design approach where objects can subscribe as observers of events that other objects are publishing. The publisher(s) of the events then just broadcasts the events to all of the subscribers. This allows the creation of an extensible, loosely-coupled framework of notifications, since the publisher(s) don't require any specific knowledge of the observers. The pubsub module provided by the wx.lib package provides an easy-to-use implementation of the observer pattern through a publisher/subscriber approach. Any arbitrary number of objects can subscribe their own callback methods to messages that the publishers will send to make their notifications. This recipe shows how to use the pubsub module to send configuration notifications in an application. How to do it... Here, we will create our application configuration object that stores runtime configuration variables for an application and provides a notification mechanism for whenever a value is added or modified in the configuration, through an interface that uses the observer pattern: import wx from wx.lib.pubsub import Publisher # PubSub message classification MSG_CONFIG_ROOT = ('config',) class Configuration(object): """Configuration object that provides notifications. """ def __init__(self): super(Configuration, self).__init__() # Attributes self._data = dict() def SetValue(self, key, value): self._data[key] = value # Notify all observers of config change Publisher.sendMessage(MSG_CONFIG_ROOT + (key,), value) def GetValue(self, key): """Get a value from the configuration""" return self._data.get(key, None) Now, we will create a very simple application to show how to subscribe observers to configuration changes in the Configuration class: class ObserverApp(wx.App): def OnInit(self): self.config = Configuration() self.frame = ObserverFrame(None, title="Observer Pattern") self.frame.Show() self.configdlg = ConfigDialog(self.frame, title="Config Dialog") self.configdlg.Show() return True def GetConfig(self): return self.config This dialog will have one configuration option on it to allow the user to change the applications font: class ConfigDialog(wx.Dialog): """Simple setting dialog""" def __init__(self, *args, **kwargs): super(ConfigDialog, self).__init__(*args, **kwargs) # Attributes self.panel = ConfigPanel(self) # Layout sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.panel, 1, wx.EXPAND) self.SetSizer(sizer) self.SetInitialSize((300, 300)) class ConfigPanel(wx.Panel): def __init__(self, parent): super(ConfigPanel, self).__init__(parent) # Attributes self.picker = wx.FontPickerCtrl(self) # Setup self.__DoLayout() # Event Handlers self.Bind(wx.EVT_FONTPICKER_CHANGED, self.OnFontPicker) def __DoLayout(self): vsizer = wx.BoxSizer(wx.VERTICAL) hsizer = wx.BoxSizer(wx.HORIZONTAL) vsizer.AddStretchSpacer() hsizer.AddStretchSpacer() hsizer.AddWindow(self.picker) hsizer.AddStretchSpacer() vsizer.Add(hsizer, 0, wx.EXPAND) vsizer.AddStretchSpacer() self.SetSizer(vsizer) Here, in the FontPicker's event handler, we get the newly-selected font and call SetValue on the Configuration object owned by the App object in order to change the configuration, which will then cause the ('config', 'font') message to be published: def OnFontPicker(self, event): """Event handler for the font picker control""" font = self.picker.GetSelectedFont() # Update the configuration config = wx.GetApp().GetConfig() config.SetValue('font', font) Now, here, we define the application's main window that will subscribe it's OnConfigMsg method as an observer of all ('config',) messages, so that it will be called whenever the configuration is modified: class ObserverFrame(wx.Frame): """Window that observes configuration messages""" def __init__(self, *args, **kwargs): super(ObserverFrame, self).__init__(*args, **kwargs) # Attributes self.txt = wx.TextCtrl(self, style=wx.TE_MULTILINE) self.txt.SetValue("Change the font in the config " "dialog and see it update here.") # Observer of configuration changes Publisher.subscribe(self.OnConfigMsg, MSG_CONFIG_ROOT) def __del__(self): # Unsubscribe when deleted Publisher.unsubscribe(self.OnConfigMsg) Here is the observer method that will be called when any message beginning with 'config' is sent by the pubsub Publisher. In this sample application, we just check for the ('config', 'font') message and update the font of the TextCtrl object to use the newly-configured one: def OnConfigMsg(self, msg): """Observer method for config change messages""" if msg.topic[-1] == 'font': # font has changed so update controls self.SetFont(msg.data) self.txt.SetFont(msg.data) if __name__ == '__main__': app = ObserverApp(False) app.MainLoop() How it works... This recipe shows a convenient way to manage an application's configuration by allowing the interested parts of an application to subscribe to updates when certain parts of the configuration are modified. Let's start with a quick walkthrough of how pubsub works. Pubsub messages use a tree structure to organize the categories of different messages. A message type can be defined either as a tuple ('root', 'child1', 'grandchild1') or as a dot-separated string ('root.child1.grandchild1'). Subscribing a callback to ('root',) will cause your callback method to be called for all messages that start with ('root',). This means that if a component publishes ('root', 'child1', 'grandchild1') or ('root', 'child1'), then any method that is subscribed to ('root',) will also be called Pubsub basically works by storing the mapping of message types to callbacks in static memory in the pubsub module. In Python, modules are only imported once any other part of your application that uses the pubsub module shares the same singleton Publisher object. In our recipe, the Configuration object is a simple object for storing data about the configuration of our application. Its SetValue method is the important part to look at. This is the method that will be called whenever a configuration change is made in the application. In turn, when this is called, it will send a pubsub message of ('config',) + (key,) that will allow any observers to subscribe to either the root item or more specific topics determined by the exact configuration item. Next, we have our simple ConfigDialog class. This is just a simple example that only has an option for configuring the application's font. When a change is made in the FontPickerCtrl in the ConfigPanel, the Configuration object will be retrieved from the App and will be updated to store the newly-selected Font. When this happens, the Configuration object will publish an update message to all subscribed observers. Our ObserverFrame is an observer of all ('config',) messages by subscribing its OnConfigMsg method to MSG_CONFIG_ROOT. OnConfigMsg will be called any time the Configuration object's SetValue method is called. The msg parameter of the callback will contain a Message object that has a topic and data attribute. The topic attribute will contain the tuple that represents the message that triggered the callback and the data attribute will contain any data that was associated with the topic by the publisher of the message. In the case of a ('config', 'font') message, our handler will update the Font of the Frame and its TextCtrl.
Read more
  • 0
  • 0
  • 7107

article-image-introduction-jboss-clustering
Packt
09 Dec 2010
6 min read
Save for later

Introduction to JBoss Clustering

Packt
09 Dec 2010
6 min read
Clustering plays an important role in Enterprise applications as it lets you split the load of your application across several nodes, granting robustness to your applications. As we discussed earlier, for optimal results it's better to limit the size of your JVM to a maximum of 2-2.5GB, otherwise the dynamics of the garbage collector will decrease your application's performance. Combining relatively smaller Java heaps with a solid clustering configuration can lead to a better, scalable configuration plus significant hardware savings. The only drawback to scaling out your applications is an increased complexity in the programming model, which needs to be correctly understood by aspiring architects. JBoss AS comes out of the box with clustering support. There is no all-in-one library that deals with clustering but rather a set of libraries, which cover different kinds of aspects. The following picture shows how these libraries are arranged: The backbone of JBoss Clustering is the JGroups library, which provides the communication between members of the cluster. Built upon JGroups we meet two building blocks, the JBoss Cache framework and the HAPartition service. JBoss Cache handles the consistency of your application across the cluster by means of a replicated and transactional cache. On the other hand, HAPartition is an abstraction built on top of a JGroups Channel that provides support for making and receiving RPC invocations from one or more cluster members. For example HA-JNDI (High Availability JNDI) or HA Singleton (High Availability Singleton) both use HAPartition to share a single Channel and multiplex RPC invocations over it, eliminating the configuration complexity and runtime overhead of having each service create its own Channel. If you need more information about the HAPartition service you can consult the JBoss AS documentation https://developer.jboss.org/wiki/jBossAS5ClusteringGuide. In the next section we will learn more about the JGroups library and how to configure it to reach the best performance for clustering communication. Configuring JGroups transport Clustering requires communication between nodes to synchronize the state of running applications or to notify changes in the cluster definition. JGroups (http://jgroups.org/manual/html/index.html) is a reliable group communication toolkit written entirely in Java. It is based on IP multicast, but extends by providing reliability and group membership. Member processes of a group can be located on the same host, within the same Local Area Network (LAN), or across a Wide Area Network (WAN). A member can be in turn part of multiple groups. The following picture illustrates a detailed view of JGroups architecture: A JGroups process consists basically of three parts, namely the Channel, Building blocks, and the Protocol stack. The Channel is a simple socket-like interface used by application programmers to build reliable group communication applications. Building blocks are an abstraction interface layered on top of Channels, which can be used instead of Channels whenever a higher-level interface is required. Finally we have the Protocol stack, which implements the properties specified for a given channel. In theory, you could configure every service to bind to a different Channel. However this would require a complex thread infrastructure with too many thread context switches. For this reason, JBoss AS is configured by default to use a single Channel to multiplex all the traffic across the cluster. The Protocol stack contains a number of layers in a bi-directional list. All messages sent and received over the channel have to pass through all protocols. Every layer may modify, reorder, pass or drop a message, or add a header to a message. A fragmentation layer might break up a message into several smaller messages, adding a header with an ID to each fragment, and re-assemble the fragments on the receiver's side. The composition of the Protocol stack (that is, its layers) is determined by the creator of the channel: an XML file defines the layers to be used (and the parameters for each layer). Knowledge about the Protocol stack is not necessary when just using Channels in an application. However, when an application wishes to ignore the default properties for a Protocol stack, and configure their own stack, then knowledge about what the individual layers are supposed to do is needed. In JBoss AS, the configuration of the Protocol stack is located in the file, <server> deployclusterjgroups-channelfactory.sarMETA-INFjgroupschannelfactory- stacks.xml. The file is quite large to fit here, however, in a nutshell, it contains the following basic elements: The first part of the file includes the UDP transport configuration. UDP is the default protocol for JGroups and uses multicast (or, if not available, multiple unicast messages) to send and receive messages. A multicast UDP socket can send and receive datagrams from multiple clients. The interesting and useful feature of multicast is that a client can contact multiple servers with a single packet, without knowing the specific IP address of any of the hosts. Next to the UDP transport configuration, three protocol stacks are defined: udp: The default IP multicast based stack, with flow control udp-async: The protocol stack optimized for high-volume asynchronous RPCs udp-sync: The stack optimized for low-volume synchronous RPCs Thereafter, the TCP transport configuration is defined . TCP stacks are typically used when IP multicasting cannot be used in a network (for example, because it is disabled) or because you want to create a network over a WAN (that's conceivably possible but sharing data across remote geographical sites is a scary option from the performance point of view). You can opt for two TCP protocol stacks: tcp: Addresses the default TCP Protocol stack which is best suited to high-volume asynchronous calls. tcp-async: Addresses the TCP Protocol stack which can be used for low-volume synchronous calls. If you need to switch to TCP stack, you can simply include the following in your command line args that you pass to JBoss: -Djboss.default.jgroups.stack=tcp Since you are not using multicast in your TCP communication, this requires configuring the addresses/ports of all the possible nodes in the cluster. You can do this by using the property -Djgroups.tcpping. initial_hosts. For example: -Djgroups.tcpping.initial_hosts=host1[7600],host2[7600] Ultimately, the configuration file contains two stacks which can be used for optimising JBoss Messaging Control Channel (jbm-control) and Data Channel (jbm-data).
Read more
  • 0
  • 0
  • 2549

article-image-microsoft-enterprise-library-security-application-block
Packt
09 Dec 2010
5 min read
Save for later

Microsoft Enterprise Library: Security Application Block

Packt
09 Dec 2010
5 min read
Microsoft Enterprise Library 5.0 Develop Enterprise applications using reusable software components of Microsoft Enterprise Library 5.0 Develop Enterprise Applications using the Enterprise Library Application Blocks Set up the initial infrastructure configuration of the Application Blocks using the configuration editor A step-by-step tutorial to gradually configure each Application Block and implement its functions to develop the required Enterprise Application The first step is the process of validating an identity against a store (Active Directory, Database, and so on); this is commonly called as Authentication. The second step is the process of verifying whether the validated identity is allowed to perform certain actions; this is commonly known Authorization. These two security mechanisms take care of allowing only known identities to access the application and perform their respective actions. Although, with the advent of new tools and technologies, it is not difficult to safeguard the application, utilizing these authentication and authorization mechanisms and implementing security correctly across different types of applications, or across different layers and in a consistent manner is pretty challenging for developers. Also, while security is an important factor, it's of no use if the application's performance is dismal. So, a good design should also consider performance and cache the outcome of authentication and authorization for repeated use. The Security Application Block provides a very simple and consistent way to implement authorization and credential caching functionality in our applications. Authorization doesn't belong to one particular layer; it is a best practice to authorize user action not only in the UI layer but also in the business logic layer. As Enterprise Library application blocks are layer-agnostic, we can leverage the same authorization rules and expect the same outcome across different layers bringing consistency. Authorization of user actions can be performed using an Authorization Provider; the block provides Authorization Rule Provider or AzMan Authorization Provider; it also provides the flexibility of implementing a custom authorization provider. Caching of security credentials is provided by the SecurityCacheProvider by leveraging the Caching Application Block and a custom caching provider can also be implemented using extension points. Both Authorization and Security cache providers are configured in the configuration file; this allows changing of provider any time without re-compilation. The following are the key features of the Security block: The Security Application Block provides a simple and consistent API to implement authorization. It abstracts the application code from security providers through configuration. It provides the Authorization Rule Provider to store rules in a configuration file and Windows Authorization Manager (AzMan) Authorization Provider to authorize against Active Directory, XML file, or database. Flexibility to implement custom Authorization Providers. It provides token generation and caching of authenticated IIdentity, IPrincipal and Profile objects. It provides User identity cache management, which improves performance while repeatedly authenticating users using cached security credentials. Flexibility to extend and implement custom Security Cache Providers. Developing an application We will explore each individual Security block feature and along the way we will understand the concepts behind the individual elements. This will help us to get up to speed with the basics. To get started, we will do the following: Reference the Validation block assemblies Add the required Namespaces Set up the initial configuration To complement the concepts and allow you to gain quick hands-on experience of different features of the Security Application Block, we have created a sample web application project with three additional projects, DataProvider, BusinessLayer, and BusinessEntities, to demonstrate the features. The application leverages SQL Membership, Role, and Profile provider for authentication, role management, and profiling needs. Before running the web application you will have to run the database generation script provided in the DBScript folder of the solution, and update the connection string in web.config appropriately. You might have to open the solution in "Administrator" mode based on your development environment. Also, create an application pool with an identity that has the required privileges to access the development SQL Server database, and map the application pool to the website. A screenshot of the sample application is shown as follows: (Move the mouse over the image to enlarge.) Referencing required/optional assemblies For the purposes of this demonstration we will be referencing non-strong-named assemblies but based on individual requirements Microsoft strong-named assemblies, or a modified set of custom assemblies can be referenced as well. The list of Enterprise Library assemblies that are required to leverage the Security Application Block functionality is given next. A few assemblies are optional based on the Authorization Provider and cache storage mechanism used. Use the Microsoft strong-named, or the non-strong-named, or a modified set of custom assemblies based on your referencing needs. The following table lists the required/optional assemblies: AssemblyRequired/OptionalMicrosoft.Practices.EnterpriseLibrary.Common.dllRequiredMicrosoft.Practices.ServiceLocation.dllRequiredMicrosoft.Practices.Unity.dllRequiredMicrosoft.Practices.Unity.Interception.dllRequiredMicrosoft.Practices.Unity.Configuration.dll Optional Useful while utilizing Unity configuration classes in our code Microsoft.Practices.EnterpriseLibrary.Security.dllRequiredMicrosoft.Practices.EnterpriseLibrary.Security.AzMan.dll Optional Used for Windows Authorization Manager Provider Microsoft.Practices.EnterpriseLibrary.Security.Cache.CachingStore.dll Optional Used for caching the User identity Microsoft.Practices.EnterpriseLibrary.Data.dll Optional Used for caching in Database Cache Storage Open Visual Studio 2008/2010 and create a new ASP.NET Web Application Project by selecting File | New | Project | ASP.NET Web Application; provide the appropriate name for the solution and the desired project location. Currently, the application will have a default web form and assembly references. In the Solution Explorer, right-click on the References section and click on Add Reference and go to the Browse tab. Next, navigate to the Enterprise Library 5.0 installation location; the default install location is %Program Files%Microsoft Enterprise Library 5.0Bin. Now select all the assemblies listed in the previous table, excluding the AzMan-related assembly (Microsoft.Practices.EnterpriseLibrary.Security.AzMan.dll). The final assembly selection will look similar to the following screenshot:
Read more
  • 0
  • 0
  • 3274
article-image-joomla-books-packt
Packt
08 Dec 2010
2 min read
Save for later

Joomla! Books from Packt

Packt
08 Dec 2010
2 min read
Joomla! 1.5: Beginner's Guide Published: March 2010 Joomla! 1.5 Multimedia Published: February 2010 Joomla! 1.5 Templates Cookbook Published: July 2010   Joomla! 1.5x CustomizationPublished: August 2009   Mastering Joomla! 1.5 Extension and Framework Development Published: November 2007     Bundle Price: $175.95/ £92.95/ €136.95 Packt special offer: $40/ £25 / €30(save $135.95/ £67.95/ €106.95)You can buy all 5 of these Joomla! ebooks with just one click.           You may also be interested in our other Joomla! titles: Joomla! 1.5 Top Extensions Cookbook Over 80 great recipes for taking control of Joomla! Extensions. Click for more information Joomla! 1.5 Cookbook Over 60 quick and direct recipes to help you overcome common Joomla! queries. Click for more information ChronoForms 3.1 for Joomla! site Cookbook 80 recipes for building attractive and interactive Joomla! forms. Click for more information Joomla! 1.5 JavaScript jQuery Enhance your Joomla! Sites with the power of jQuery extensions, plugins, and more. Click for more information Joomla! Social Networking with JomSocial Learn how to develop a high quality social network using JomSocial. Click for more information Joomla! 1.5 Templates Cookbook Over 60 simple but incredibly effective recipes for taking control of Joomla! templates. Click for more information Mastering Joomla! 1.5 Extension and Framework Development Second Edition Extend the power of Joomla! by adding components, modules, plugins, and other extensions Click for more information Joomla! 1.5 Site Blueprints Tailor-made plans for easily building powerful and exciting Joomla! sites. Click for more information Joomla! 1.5 Multimedia Build media-rich Joomla! web sites by learning to embed and display Multimedia content. Click for more information Joomla! 1.5: Beginner's Guide Build and maintain impressive user-friendly web sites the fast and easy way with Joomla! 1.5. Click for more information
Read more
  • 0
  • 0
  • 969

article-image-python-3-object-oriented-design
Packt
08 Dec 2010
8 min read
Save for later

Python 3: Object-Oriented Design

Packt
08 Dec 2010
8 min read
Python 3 Object Oriented Programming Harness the power of Python 3 objects Learn how to do Object Oriented Programming in Python using this step-by-step tutorial Design public interfaces using abstraction, encapsulation, and information hiding Turn your designs into working software by studying the Python syntax Raise, handle, define, and manipulate exceptions using special error objects Implement Object Oriented Programming in Python using practical examples      Object-oriented? Everyone knows what an object is: a tangible "something" that we can sense, feel, and manipulate. The earliest objects we interact with are typically baby toys. Wooden blocks, plastic shapes, and over-sized puzzle pieces are common first objects. Babies learn quickly that certain objects do certain things. Triangles fit in triangle-shaped holes. Bells ring, buttons press, and levers pull. The definition of an object in software development is not so very different. Objects are not typically tangible somethings that you can pick up, sense, or feel, but they are models of somethings that can do certain things and have certain things done to them. Formally, an object is a collection of data and associated behaviors. So knowing what an object is, what does it mean to be object-oriented? Oriented simply means directed toward. So object-oriented simply means, "functionally directed toward modeling objects". It is one of many techniques used for modeling complex systems by describing a collection of interacting objects via their data and behavior. If you've read any hype, you've probably come across the terms object-oriented analysis, object-oriented design, object-oriented analysis and design, and object-oriented programming. These are all highly related concepts under the general object-oriented umbrella. In fact, analysis, design, and programming are all stages of software development. Calling them object-oriented simply specifies what style of software development is being pursued. Object-oriented Analysis (OOA) is the process of looking at a problem, system, or task that somebody wants to turn into an application and identifying the objects and interactions between those objects. The analysis stage is all about what needs to be done. The output of the analysis stage is a set of requirements. If we were to complete the analysis stage in one step, we would have turned a task, such as, "I need a website", into a set of requirements, such as: Visitors to the website need to be able to (italic represents actions, bold represents objects): review our history apply for jobs browse, compare, and order our products Object-oriented Design (OOD) is the process of converting such requirements into an implementation specification. The designer must name the objects, define the behaviors, and formally specify what objects can activate specific behaviors on other objects. The design stage is all about how things should be done. The output of the design stage is an implementation specification. If we were to complete the design stage in one step, we would have turned the requirements into a set of classes and interfaces that could be implemented in (ideally) any object-oriented programming language. Object-oriented Programming (OOP) is the process of converting this perfectly defined design into a working program that does exactly what the CEO originally requested. Yeah, right! It would be lovely if the world met this ideal and we could follow these stages one by one, in perfect order like all the old textbooks told us to. As usual, the real world is much murkier. No matter how hard we try to separate these stages, we'll always find things that need further analysis while we're designing. When we're programming, we find features that need clarification in the design. In the fast-paced modern world, most development happens in an iterative development model. In iterative development, a small part of the task is modeled, designed, and programmed, then the program is reviewed and expanded to improve each feature and include new features in a series of short cycles. In this article we will cover the basic object-oriented principles in the context of design. This allows us to understand these rather simple concepts without having to argue with software syntax or interpreters. Objects and classes So, an object is a collection of data with associated behaviors. How do we tell two types of objects apart? Apples and oranges are both objects, but it is a common adage that they cannot be compared. Apples and oranges aren't modeled very often in computer programming, but let's pretend we're doing an inventory application for a fruit farm! As an example, we can assume that apples go in barrels and oranges go in baskets. Now, we have four kinds of objects: apples, oranges, baskets, and barrels. In object-oriented modeling, the term used for kinds of objects is class. So, in technical terms, we now have four classes of objects. What's the difference between an object and a class? Classes describe objects. They are like blueprints for creating an object. You might have three oranges sitting on the table in front of you. Each orange is a distinct object, but all three have the attributes and behaviors associated with one class: the general class of oranges. The relationship between the four classes of objects in our inventory system can be described using a Unified Modeling Language (invariably referred to as UML, because three letter acronyms are cool) class diagram. Here is our first class diagram: This diagram simply shows that an Orange is somehow associated with a Basket and that an Apple is also somehow associated with a Barrel. Association is the most basic way for two classes to be related. UML is very popular among managers, and occasionally disparaged by programmers. The syntax of a UML diagram is generally pretty obvious; you don't have to read a tutorial to (mostly) understand what is going on when you see one. UML is also fairly easy to draw, and quite intuitive. After all, many people, when describing classes and their relationships, will naturally draw boxes with lines between them. Having a standard based on these intuitive diagrams makes it easy for programmers to communicate with designers, managers, and each other. However, some programmers think UML is a waste of time. Citing iterative development, they will argue that formal specifications done up in fancy UML diagrams are going to be redundant before they're implemented, and that maintaining those formal diagrams will only waste time and not benefit anyone. This is true of some organizations, and hogwash in other corporate cultures. However, every programming team consisting of more than one person will occasionally have to sit down and hash out the details of part of the system they are currently working on. UML is extremely useful, in these brainstorming sessions, for quick and easy communication. Even those organizations that scoff at formal class diagrams tend to use some informal version of UML in their design meetings, or team discussions. Further, the most important person you ever have to communicate with is yourself. We all think we can remember the design decisions we've made, but there are always, "Why did I do that?" moments hiding in our future. If we keep the scraps of paper we did our initial diagramming on when we started a design, we'll eventually find that they are a useful reference. UML covers far more than class and object diagrams; it also has syntax for use cases, deployment, state changes, and activities. We'll be dealing with some common class diagram syntax in this discussion of object-oriented design. You'll find you can pick up the structure by example, and you'll subconsciously choose UML-inspired syntax in your own team or personal design sessions. Our initial diagram, while correct, does not remind us that apples go in barrels or how many barrels a single apple can go in. It only tells us that apples are somehow associated with barrels. The association between classes is often obvious and needs no further explanation, but the option to add further clarification is always there. The beauty of UML is that most things are optional. We only need to specify as much information in a diagram as makes sense for the current situation. In a quick whiteboard session, we might just quickly draw lines between boxes. In a formal document that needs to make sense in six months, we might go into more detail. In the case of apples and barrels, we can be fairly confident that the association is, "many apples go in one barrel", but just to make sure nobody confuses it with, "one apple spoils one barrel", we can enhance the diagram as shown: This diagram tells us that oranges go in baskets with a little arrow showing what goes in what. It also tells us the multiplicity (number of that object that can be used in the association) on both sides of the relationship. One Basket can hold many (represented by a *) Orange objects. Any one Orange can go in exactly one Basket. It can be easy to confuse which side of a relationship the multiplicity goes on. The multiplicity is the number of objects of that class that can be associated with any one object at the other end of the association. For the apple goes in barrel association, reading from left to right, many instances of the Apple class (that is many Apple objects) can go in any one Barrel. Reading from right to left, exactly one Barrel can be associated with any one Apple.
Read more
  • 0
  • 0
  • 3974

article-image-creating-content-drupal-7
Packt
03 Dec 2010
3 min read
Save for later

Creating Content in Drupal 7

Packt
03 Dec 2010
3 min read
Drupal 7 First Look Learn the new features of Drupal 7, how they work and how they will impact you Get to grips with all of the new features in Drupal 7 Upgrade your Drupal 6 site, themes, and modules to Drupal 7 Explore the new Drupal 7 administration interface and map your Drupal 6 administration interface to the new Drupal 7 structure Complete coverage of the DBTNG database layer with usage examples and all API changes for both Themes and Modules         Read more about this book       (For more resources on Drupal 7, see here.) Creating content for your site is at the core of any Content Management System like Drupal. The primary changes for Drupal 7 relate to an updated interface. Let's look at the new interface in detail. Selecting a content type to create To create content in Drupal 7, first log in to your site and then click on Content from the site toolbar. Drupal will now display the new Content Administration page. Move mouse over the image to enlarge it. In Drupal 6, this page could be displayed by selecting Administer | Content Management | Content from the Navigation menu. From here, click on the Add new content link. Drupal will now display a page allowing you to select the type of content you want to create. Depending on the modules you have installed and enabled, you will have different content types available. In previous versions of Drupal, this page could be reached by selecting the Create Content link from the Navigation menu. You can also select the type of content to add using the shortcut bar. You can access the shortcut bar by clicking on the toggle at the far right of the toolbar: The shortcut bar has a list of links in it that can be used to quickly access commonly used functionality, and it appears as follows: You can customize the links in the shortcut bar and users can use either the default set of shortcuts or they can have their own. Now select the type of content you want to create. For this example, we will use the Basic page type. Content UI The interface to create content has been altered drastically from Drupal 6. Let's go through the interface in detail. The top section of the page should be familiar to experienced editors. This is the place to enter your title as well as the full text of the page. In a departure from previous versions, the node summary, which is used when multiple nodes are displayed on a page, is an entirely separate optional field.
Read more
  • 0
  • 1
  • 4436
article-image-building-admin-interface-drupal-7
Packt
03 Dec 2010
11 min read
Save for later

Building an admin interface in Drupal 7

Packt
03 Dec 2010
11 min read
The User Warn module In this article we will be creating the User Warn module. This module allows administrators to send users a warning via e-mail when that user violates a site's terms of service or otherwise behaves in a way that is inappropriate. The User Warn module will implement the following features: The module will expose configuration settings to site administrators, including default mail text This e-mail will include Drupal tokens, which allow the admin to replace and/or add site-specific variables to the e-mail Site administrators will be able to send a user mail via a new tab on their user profile page Warning e-mails will be sent using Drupal's default mail implementation Starting our module We will begin by creating a new folder for our module called user_warn in the sites/default/modules directory in our Drupal installation. We can then create a user_warn.info file as shown in the following: ;$Id$ name = User Warn description = Exposes an admin interface to send behavior warning e-mails to users. core = 7.x package = Drupal 7 Development files[] = user_warn.module You should be pretty familiar with this now. We will also create our user_warn.module file and add an implementation of hook_help() to let site administrators know what our module does. http://api.drupal.org/api/function/hook_menu/7 The example is as follows: /** * Implement hook_menu(). */ function user_warn_menu() { $items = array(); $items['admin/config/people/user_warn'] = array( 'title' => 'User Warn', 'description' => 'Configuration for the User Warn module.', 'page callback' => 'drupal_get_form', 'page arguments' => array('user_warn_form'), 'access arguments' => array('administer users'), 'type' => MENU_NORMAL_ITEM, ); $items['user/%/warn'] = array( 'title' => 'Warn', 'description' => 'Send e-mail to a user about improper site behavior.', 'page callback' => 'drupal_get_form', 'page arguments' => array('user_warn_confirm_form', 1), 'access arguments' => array('administer users'), 'type' => MENU_LOCAL_TASK, ); return $items; } Like many Drupal hook implementations, hook_menu() returns a structured associative array with information about the menu items being defined. The first item in our example defines the module configuration page, and the second one defines the user tab where administrators can go to send the actual e-mail. Let's look at the first item in more detail. Menu items are keyed off their path. This is an internal Drupal path with no leading or trailing slashes. This path not only defines the location of a page, but also its place in the menu hierarchy, with each part of the URL being a child of the last. In this example, people is a child of config which is itself a child of admin. If a requested path does not exist, Drupal will work its way up the hierarchy until it encounters a page that does exist. You can see this in action by requesting admin/config/people/xyzzy which displays the page at admin/config/people. If you are creating a menu item for site administration it must begin with admin. This places it into Drupal's administrative interface and applies the admin theme defined by the site settings. Module-specific settings should always be present under admin/config. Drupal 7 offers several categories which module developers should use to better organize their settings according to Drupal functional groups like People and Permissions or Content Authoring. The value associated with this key is itself an associative array with several keys that define what action should be taken when this URL is requested. We can now look at those in detail. The first item defines your page title: 'title' => 'User Warn', This is used in a variety of display contexts—as your page's heading, in the HTML &lttitle&gt tag and as a subheading in the administration interface in combination with the description (if you are defining an administrative menu item). 'description' => 'Configuration for the User Warn module.', The description is just that—a longer text description of the page that this menu item defines. This should provide the user with more detailed information about the actions they can take on this page. This description is also used as the title tag when you hover over a link. Menu item titles and descriptions are passed through t() internally by Drupal, so this is one case where we don't need to worry about doing that ourselves. For an administration page, these two items define how your page is listed in Drupal's admin area as shown in the following: The next two items define what will happen when your page is requested: 'page callback' => 'drupal_get_form', 'page arguments' => array('user_warn_form'), 'page callback' defines the function that will get called (without the parentheses) and 'page arguments' contains an array of arguments that get passed to this function. Often you will create a custom function that processes, formats, and returns specific data. However, in our case we are calling the internal Drupal function drupal_get_form() that returns an array as defined by Drupal's Form API. As an argument we are passing the form ID of the form we want to display. The fifth item controls who can access your page. 'access arguments' => array('administer users'), 'access arguments' takes an array containing a permissions strings. Any user who has been assigned one of these permissions will be able to access this page. Anyone else will be given an Access denied page. Permissions are defined by modules using hook_permission(). You can see a full list of the currently defined permissions at admin/people/permissions as shown: You can see the 'administer users' permission at the bottom of this list. In the preceding example, only the Administrator role has this permission, and as a result only those users assigned this role will be able to access our page. Note that the titles of the permissions here do not necessarily match what you will need to enter in the access arguments array. Unfortunately, the only good way to find this information is by checking the hook_perm() implementation of the module in question. The final item defines what type of menu item we are creating: 'type' => MENU_NORMAL_ITEM, The 'type' is a bitmask of flags that describe what features we want our menu item to have (for instance, whether it is visible in the breadcrumb trail). Drupal defines over 20 constants for menu items that should cover any situation developers will find themselves in. The default type is MENU_NORMAL_ITEM, which indicates that this item will be visible in the menu tree as well as the breadcrumb trail. This is all the information that is needed to register our path. Now when Drupal receives a request for this URL, it will return the results of drupal_get_form(user_warn_form). Drupal caches the entire menu, so new/updated menu items will not be reflected immediately. To manually clear the cache, visit Admin | Configuration | Development | Performance and click on Clear all caches. Using wildcards in menu paths We have created a simple menu item, but sometimes simple won't do the job. In the User Warn module we want to have a menu item that is tied to each individual user's profile page. Profile pages in Drupal live at the path user/&ltuser_id&gt, so how do we create a distinct menu item for each user? Fortunately the menu system allows us to use wildcards when we define our menu paths. If you look at the second menu item defined in the preceding example, you will see that its definition differs a bit from our first example. $items['user/%/warn'] = array( 'title' => 'Warn', 'description' => 'Send e-mail to a user about improper site behavior.', 'page callback' => 'drupal_get_form', 'page arguments' => array('user_warn_confirm_form', 1), 'access arguments' => array('administer users'), 'type' => MENU_LOCAL_TASK, ); The first difference is that the path is defined with % as one of the path entries. This indicates a wildcard; anything can be entered here and the menu item's hierarchy will be maintained. In Drupal, that will always be a user's ID. However, there is nothing stopping any user from entering a URL like user/xyzzy/warn or something else potentially more malicious. Your code should always be written in such a way as to handle these eventualities, for instance by verifying that the argument actually maps to a Drupal user. This would be a good improvement. The other difference in this example is that we have added 1 as an additional argument to be passed to our page callback. Each argument in a menu item's path can be accessed as an argument that is available to be passed to our page callback, starting with 0 for the root argument. So here the string user is item 0, and the user's ID is item 1. To use the user's ID as a page callback argument, we reference it by its number. The result in this case is that the user's ID will be passed as an additional argument to drupal_get_form(). We have one other difference in this second menu item: 'type' => MENU_LOCAL_TASK, We have defined our type as MENU_LOCAL_TASK. This tells Drupal that our menu item describes actions that can be performed on the parent item. In this example, Warn is an action that can be performed on a user. These are usually rendered as an additional tab on the page in question, as you can see in the following example user profile screen: Having defined the paths for our pages through hook_menu(), we now need to build our forms. Form API In standard web development, one of the most tedious and unrewarding tasks is defining HTML forms and handling their submissions. Lay out the form, create labels, write the submission function, figure out error handling, and the worst part is that from site to site much of this code is boilerplate—it's fundamentally the same, differing only in presentation. Drupal's Form API is a powerful tool allowing developers to create forms and handle form submissions quickly and easily. This is done by defining arrays of form elements and creating validation and submit callbacks for the form. In past versions of Drupal, Form API was commonly referred to as FAPI. However, Drupal 7 now has three APIs which could fit this acronym—Form API, Field API and File API. We will avoid using the acronym FAPI completely, to prevent confusion, but you will still encounter it widely in online references. Form API is also a crucial element in Drupal's security. It provides unique form tokens that are verified on form submission, preventing Cross-site Request Forgery attacks, and automatically validating required fields, field lengths, and a variety of other form element properties. Using drupal_get_form() In our first menu implementation seen earlier, we defined the page callback as drupal_get_form(). This Form API function returns a structured array that represents an HTML form. This gets rendered by Drupal and presented as an HTML form for the user. drupal_get_form() takes a form ID as a parameter. This form ID can be whatever you want, but it must be unique within Drupal. Typically it will be &ltmodule_name&gt_&ltdescription&gt_form. The form ID is also the name of the callback function drupal_get_form() will call to build your form. The specified function should return a properly formatted array containing all the elements your form needs. Since the form ID also serves as the form's callback function, it must be a valid PHP variable name. Spaces and hyphens are not allowed. All form IDs should be prefaced by the name of your module followed by an underscore, in order to prevent name collision. Other parameters can be passed into drupal_get_form() in addition to the form ID. These extra parameters simply get passed through to the callback function for its own use. In Drupal 6, drupal_get_form() returned a fully rendered HTML form. This has been changed in Drupal 7 in order to allow more flexibility in theming and easier form manipulation. drupal_get_form() now returns an unrendered form array which must be passed to drupal_render() for final output. In the preceding example the menu system handles the change transparently, but other code converted from Drupal 6 may need to be changed.
Read more
  • 0
  • 0
  • 4475

article-image-new-sap-books-packt-enterprise
Packt
02 Dec 2010
1 min read
Save for later

New SAP Books from Packt Enterprise

Packt
02 Dec 2010
1 min read
Mastering SQL Queries for SAP Business One Utilise the power of SQL queries to bring Business Intelligence to your small to medium-sized business SAP BusinessObjects Dashboards 4.0 Cookbook Over 90 simple and incredibly effective recipes for transforming your business data into exciting dashboards with SAP BusinessObjects Dashboards 4.0 Xcelcius SAP Netweaver MDM 7.1 for Functional Consultants : RAW Don't just manage – Excel at managing your master data. This book is written in an easy-to-read style, with a strong emphasis on real-world, practical examples with step-by-step explanations SAP Business ONE Implementation Bring the power of SAP Enterprise Resource Planning to your small-midsize business SAP Business ONE Implementation: LITE Quick start with an Agile Implementation, Reporting and Data Migration
Read more
  • 0
  • 0
  • 1415
Modal Close icon
Modal Close icon