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-miscellaneous-gameplay-features
Packt
01 Mar 2013
13 min read
Save for later

Miscellaneous Gameplay Features

Packt
01 Mar 2013
13 min read
(For more resources related to this topic, see here.) How to have a sprinting player use up energy Torque 3D's Player class has three main modes of movement over land: sprinting, running, and crouching. Some are designed to allow a player to sprint as much as they want, but perhaps with other limitations while sprinting. This is the default method of sprinting in the Torque 3D templates. Other game designs allow the player to sprint only for short bursts before the player becomes "tired". In this recipe, we will learn how to set up the Player class such that sprinting uses up a pool of energy that slowly recharges over time; and when that energy is depleted, the player is no longer able to sprint. How to do it... We are about to modify a PlayerData Datablock instance so that sprint uses up the player's energy as follows: Open your player's Datablock in a text editor, such as Torsion. The Torque 3D templates have the DefaultPlayerData Datablock template in art/ datablocks/player.cs. Find the sprinting section of the Datablock instance and make the following changes: sprintForce = 4320; sprintEnergyDrain = 0.6; // Sprinting now drains energy minSprintEnergy = 10; // Minimum energy to sprint maxSprintForwardSpeed = 14; maxSprintBackwardSpeed = 8; maxSprintSideSpeed = 6; sprintStrafeScale = 0.25; sprintYawScale = 0.05; sprintPitchScale = 0.05; sprintCanJump = true; Start up the game and have the player sprint. Sprinting should now be possible for about 5.5 seconds before the player falls back to a run. If the player stops sprinting for about 7.5 seconds, their energy will be fully recharged and they will be able to sprint again. How it works... The maxEnergy property on the PlayerData Datablock instance determines the maximum amount of energy a player has. All of Torque 3D's templates set it to a value of 60. This energy may be used for a number of different activities (such as jet jumping), and even certain weapons may draw from it. By setting the sprintEnergyDrain property on the PlayerData Datablock instance to a value greater than zero, the player's energy will be drained every tick (about one-thirty-second of a second) by that amount. When the player's energy reaches zero they may no longer sprint, and revert back to running. Using our previous example, we have a value for the sprintEnergyDrain property of 0.6 units per tick. This works out to 19.2 units per second. Given that our DefaultPlayerData maxEnergy property is 60 units, we should run out of sprint energy in 3.125 seconds. However, we were able to sprint for about 5.5 seconds in our example before running out of energy. Why is this? A second PlayerData property affects energy use over time: rechargeRate. This property determines how much energy is restored to the player per tick, and is set to 0.256 units in DefaultPlayerData. When we take both the sprintEnergyDrain and recharcheRate properties into account, we end up with an effective rate of (0.6 – 0.256) 0.344 units drained per tick while sprinting. Assuming the player begins with the maximum amount of energy allowed by DefaultPlayerData, this works out to be (60 units / (0.344 units per tick * 32 ticks per second)) 5.45 seconds. The final PlayerData property that affects sprinting is minSprintEnergy. This property determines the minimum player energy level required before being able to sprint. When this property is greater than zero, it means that a player may continue to sprint until their energy is zero, but cannot sprint again until they have regained a minSprintEnergy amount of energy. There's more... Let's continue our discussion of player sprinting and energy use. Balance energy drain versus recharge rate With everything set up as described previously, every tick the player is sprinting his energy pool will be reduced by the value of sprintEnergyDrain property of PlayerData, and increased by the value of the rechargeRate property. This means that in order for the player's energy to actually drain, his sprintEnergyDrain property must be greater than his rechargeRate property. As a player's energy may be used for other game play elements (such as jet jumping or weapons fire), sometimes we may forget this relationship while tuning the rechargeRate property, and end up breaking a player's ability to sprint (or make them sprint far too long). Modifying other sprint limitations The way the DefaultPlayerData Datablock instance is set up in all of Torque 3D's templates, there are already limitations placed on sprinting without making use of an energy drain. This includes not being able to rotate the player as fast as when running, and limited strafing ability. Making sprinting rely on the amount of energy a player has is often enough of a limitation, and the other default limitations may be removed or reduced. In the end it depends on the type of game we are making. To change how much the player is allowed to rotate while sprinting, we modify the sprintYawScale and sprintPitchScale properties of the PlayerData property. These two properties represent the fraction of rotation allowed while sprinting compared with running and default to 0.05 each. To change how much the player is allowed to strafe while sprinting, we modify the sprintStrafeScale property of the PlayerData property. This property is the fraction of the amount of strafing movement allowed while running and defaults to 0.25. Disabling sprint During a game we may want to disable a player's sprinting ability. Perhaps they are too injured, or are carrying too heavy a load. To allow or disallow sprinting for a specific player we call the following Player class method on the server: Player.allowSprinting( allow ); In the previous code, the allow parameter is set to true to allow a player the ability to sprint, and to false to not allow a player to sprint at all. This method is used by the standard weapon mounting system in scripts/server/ weapon.cs to disable sprinting. If the ShapeBaseImageData Datablock instance for the weapon has a dynamic property of sprintDisallowed set to true, the player may not sprint while holding that weapon. The DeployableTurretImage Datablock instance makes use of this by not allowing the player to sprint while holding a turret. Enabling and disabling air control Air control is a fictitious force used by a number of games that allows a player to control their trajectory while falling or jumping in the air. Instead of just falling or jumping and hoping for the best, this allows the player to change course as necessary and trades realism for playability. We can find this type of control in first-person shooters, platformers, and adventure games. In this recipe we will learn how to enable or disable air control for a player, as well as limit its effect while in use. How to do it... We are about to modify a PlayerData Datablock instance to enable complete air control as follows: Open your player's Datablock in a text editor, such as Torsion. The Torque 3D templates have the DefaultPlayerData Datablock instance in art/ datablocks/player.cs. Find the section of the Datablock instance that contains the airControl property and make the following change: jumpForce = "747"; jumpEnergyDrain = 0; minJumpEnergy = 0; jumpDelay = "15"; // Set to maximum air control airControl = 1.0; Start up the game and jump the player off of a building or a sand dune. While in the air press one of the standard movement keys: W, A, S, and D. We now have full trajectory control of the player while they are in the air as if they were running. How it works... If the player is not in contact with any surface and is not swimming, the airControl property of PlayerData is multiplied against the player's direction of requested travel. This multiplication only happens along the world's XY plane and does not affect vertical motion. Setting the airControl property of PlayerData to a value of 0 will disable all air control. Setting the airControl property to a value greater than 1 will cause the player to move faster in the air than they can run. How to jump jet In game terms, a jump jet is often a backpack, a helicopter hat, or a similar device that a player wears, that provides them a short thrust upwards and often uses up a limited energy source. This allows a player to reach a height they normally could not, jump a canyon, or otherwise get out of danger or reach a reward. In this recipe we will learn how to allow a player to jump jet. Getting ready We will be making TorqueScript changes in a project based on the Torque 3D Full template using the Empty Terrain level. If you haven't already, use the Torque Project Manager (Project Manager.exe) to create a new project from the Full template. It will be found under the My Projects directory. Then start up your favorite script editor, such as Torsion, and let's get going! How to do it... We are going to modify the player's Datablock instance to allow for jump jetting and adjust how the user triggers the jump jet as follows: Open the art/datablocks/player.cs file in your text editor. Find the DefaultPlayerData Datablock instance and just below the section on jumping and air control, add the following code: // Jump jet jetJumpForce = 500; jetJumpEnergyDrain = 3; jetMinJumpEnergy = 10; Open scripts/main.cs and make the following addition to the onStart() function: function onStart() { // Change the jump jet trigger to match a regular jump $player::jumpJetTrigger = 2; // The core does initialization which requires some of // the preferences to loaded... so do that first. exec( "./client/defaults.cs" ); exec( "./server/defaults.cs" ); Parent::onStart(); echo("n--------- Initializing Directory: scripts ---------"); // Load the scripts that start it all... exec("./client/init.cs"); exec("./server/init.cs"); // Init the physics plugin. physicsInit(); // Start up the audio system. sfxStartup(); // Server gets loaded for all sessions, since clients // can host in-game servers. initServer(); // Start up in either client, or dedicated server mode if ($Server::Dedicated) initDedicated(); else initClient(); } Start our Full template game and load the Empty Terrain level. Hold down the Space bar to cause the player to fly straight up for a few seconds. The player will then fall back to the ground. Once the player has regained enough energy it will be possible to jump jet again. How it works... The only property that is required to be set for jump jetting to work is the jetJumpForce property of the PlayerData Datablock instance. This property determines the amount of continuous force applied on the player object to have them flying up in the air. It takes some trial and error to determine what force works best. Other Datablock properties that are useful to set are jetJumpEnergyDrain and jetMinJumpEnergy. These two PlayerData properties make jet jumping use up a player's energy. When the energy runs out, the player may no longer jump jet until enough energy has recharged. The jetJumpEnergyDrain property is how much energy per tick is drained from the player's energy pool, and the jetMinJumpEnergy property is the minimum amount of energy the player needs in their energy pool before they can jump jet again. Please see the How to have a sprinting player use up energy recipe for more information on managing a player's energy use. Another change we made in our previous example is to define which move input trigger number will cause the player to jump jet. This is defined using the global $player::jumpJetTrigger variable. By default, this is set to trigger 1, which is usually the same as the right mouse button. However, all of the Torque 3D templates make use of the right mouse button for view zooming (as defined in scripts/client/default.bind.cs). In our previous example, we modified the global $player::jumpJetTrigger variable to use trigger 2, which is usually the same as for regular jumping as defined in scripts/ client/default.bind.cs: function jump(%val) { // Touch move trigger 2 $mvTriggerCount2++; } moveMap.bind( keyboard, space, jump ); This means that we now have jump jetting working off of the same key binding as regular jumping, which is the Space bar. Now holding down the Space bar will cause the player to jump jet, unless they do not have enough energy to do so. Without enough energy, the player will just do a regular jump with their legs. There's more... Let's continue our discussion of using a jump jet. Jump jet animation sequence If the shape used by the Player object has a Jet animation sequence defined, it will play while the player is jump jetting. This sequence will play instead of all other action sequences. The hierarchy or order of action sequences that the Player class uses to determine which action sequence to play is as follows: Jump jetting Falling Swimming Running (known internally as the stand pose) Crouching Prone Sprinting Disabling jump jetting During a game we may no longer want to allow a player to jump jet. Perhaps they have run out of fuel or they have removed the device that allowed them to jump jet. To allow or disallow jump jetting for a specific player, we call the following Player class method on the server: Player.allowJetJumping( allow ); In the previous code, the allow parameter is set to true to allow a player to jump jet, and to false for not allowing him to jump jet at all. More control over the jump jet The PlayerData Datablock instance has some additional properties to fine tune a player's jump jet capability. The first is the jetMaxJumpSpeed property. This property determines the maximum vertical speed at which the player may use their jump jet. If the player is moving upwards faster than this, then they may not engage their jump jet. The second is the jetMinJumpSpeed property. This property is the minimum vertical speed of the player before a speed multiplier is applied. If the player's vertical speed is between jetMinJumpSpeed and jetMaxJumpSpeed, the applied jump jet speed is scaled up by a relative amount. This helps ensure that the jump jet will always make the player move faster than their current speed, even if the player's current vertical speed is the result of some other event (such as being thrown by an explosion). Summary These recipes will help you to fully utilize the gameplay's features and make your game more interesting and powerful. The tips and tricks mentioned in the recipes will surely help you in making the game more real, more fun to play, and much more intriguing. Resources for Article : Further resources on this subject: Creating and Warping 3D Text with Away3D 3.6 [Article] Retopology in 3ds Max [Article] Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1 [Article]
Read more
  • 0
  • 0
  • 12550

article-image-integrating-microsoft-dynamics-gp-business-application-fundamentals
Packt
01 Mar 2013
5 min read
Save for later

Integrating Microsoft Dynamics GP Business Application fundamentals

Packt
01 Mar 2013
5 min read
(For more resources related to this topic, see here.) Defining the project Before you start installing software and designing windows, you need a plan. It's almost time to search for your flowcharting template, but first you need to answer this query: Just what are you trying to accomplish? Let's begin to define the project by responding to some fundamental questions: Do you want to change the way a window looks or behaves? Do you want to change or extend current Dynamics GP functionality? Do you need to create brand-new functionality? Do you need to exchange data between dissimilar systems? Are you just trying to store some additional static data? Changing a window's look or behavior Maybe the field prompts are wrong or the tabbing order is unacceptable. Perhaps there are not enough, or even too many, fields on the window. The window may need additional navigation options such as menus or buttons. You might want a field to be created only if certain criteria are met. For instance, if your customer were a reseller, the Tax Schedule ID field would not be required; but if your customer were not a reseller, the Tax Schedule ID field would be required. Maybe more visual cues should be present on the window, such as a red/green light indicator on the Customer Maintenance window to represent their payment pattern similar to the following screenshot: You may want a more obvious cue if a record note exists, like a bigger icon or an icon that flashes! You might want to see the quantity of a stock item available in the Sales Order Processing lookup window. This list could go on forever. Changing current functionality Many times Dynamics GP is just missing a little something with the way it processes certain transaction types. For example, perhaps you would like to be warned if you are entering a Payables Transaction for a vendor with an outstanding purchase order, or you need a receivables document to move to a history table automatically when you pay it, instead of having to run a monthly routine. This list does go on forever Creating new functionality This category is filled with things that Dynamics GP doesn't do at all. Dynamics GP constructed the foundation, and developers like you make its functionality boundless. Many of our vertical solutions are present here; applications for running mining operations, restaurants, and retail stores have been developed for Dynamics GP. The unique needs of a myriad of industries have been satisfied by third-party applications. Exchanging data between systems Very often, you accumulate detailed information in a different system of record and you need to import it into Dynamics GP. Sometimes you need to export information out of Dynamics GP in order to update another system. For instance, Point of Sale (POS) systems update the general ledger with daily sales, and payroll services send weekly payroll details to upload into the general ledger. Vendors send new price sheets that cause adjustments in the list price. These list price changes need to update the website as well as the accounting system. A constant stream of data flows back and forth every day and it needs to update other systems, or be updated itself. The goal is to take the information from the point of original entry, and electronically place it wherever it needs to go. We only want to touch the data once; dual entry needs to be eliminated. Our aim is to have only one version of the truth. Storing additional data Quite often the fields available for user customization, so called user-defined fields, are far too few. This problem is nearly universal when it comes to the inventory. Take, for example, a company that trades in high-end audio equipment. For a preamp they may need to know the distortion percentage, the number and types of inputs, outputs available, and so on. For speakers, they need a completely different set of information, such as sizes and types of drivers. Yes, there is much more information that needs to be at a salesperson's fingertips than the part number and the price. All of that additional information needs a place where you can enter it, and a table to call home. Types of integrations At the end of the day, there are generally two types of integrations: Database-level integrations include tasks such as the following: Importing data into Dynamics GP Exporting data out of Dynamics GP Storing additional data in new tables Synchronizing data between Dynamics GP and peripheral systems User-interface-level integrations include tasks such as the following: Adding entirely new windows Adding fields or controls to an existing window Adding navigation items to the home page Adding new menus Changing field locations on a window Changing a window's tab order A single customization often involves both types of integrations. OK, so now that the interrogation is complete, it's time to find that template and start flowcharting!
Read more
  • 0
  • 0
  • 6872

article-image-backtrack-forensics
Packt
28 Feb 2013
8 min read
Save for later

BackTrack Forensics

Packt
28 Feb 2013
8 min read
(For more resources related to this topic, see here.) Intrusion detection and log analysis Intrusion detection is a method used to monitor malicious activity on a computer network or system. It's generally referred to as an intrusion detection system (IDS) because it's the system that actually performs the task of monitoring activity based upon a set of predefined rules. An IDS adds an additional layer of security to a network by analyzing information from various points and determining if an actual or possible security breach has occurred, or to locate if a vulnerability is present that will allow for a possible breach. In this recipe, we will examine the Snort tool for the purposes of intrusion detection and log analysis. Snort was developed by Sourcefire, and is an open source tool that has the capabilities of acting as both an intrusion detection system and an intrusion prevention system. One of the advantages of Snort is that it allows you to analyze network traffic in real time, and make faster responses should security breaches occur. Remember, running Snort on our network and utilizing it for intrusion detection does not stop exploits from occurring. It just gives us the ability to see what is going on in our network. Getting ready A connection to the Internet or intranet is required to complete this task. It is assumed that you have visited http://snort.org/start/rules and downloaded the Sourcefire Vulnerability Research Team (VRT) Certified Rules. A valid ruleset must be maintained in order to use Snort for detection. If you do not have an account already, you may sign up at https://www.snort.org/signup. How to do it... Let's begin by starting Snort: Start the Snort service: Now that the Snort service has been initiated, we will start the application from a terminal window. We are going to pass a few options that are described as follows: -q: This option tells Snort to run in inline mode. -v: This command allows us to view a printout of TCP/IP headers on the screen. This is also called the "sniffer mode" setting. -c: This option allows us to select our configuration file. In this case, its location is /etc/snort/snort.conf. -i: This option allows you to specify your interface. Using these options, let's execute the following command: snort -q -v -i eth1 -c /etc/snort/snort.conf To stop Snort from monitoring, press Ctrl + X. How it works... In this recipe, we started the Snort service and launched Snort in order to view the log data. There's more… Before we can adequately use Snort for our purposes, we need to make alterations to its configuration file. Open a terminal window and locate the Snort configuration file: locate snort.conf Now we will edit the configuration file using nano: nano /etc/snort/snort.conf Look for the line that reads var HOME_NET any. We would like to change this to our internal network (the devices we would like to have monitored). Each situation is going to be unique. You may want to only monitor one device and you can do so simply by entering its IP address (var HOME_NET 192.168.10.10). You may also want to monitor an IP range (var HOME_NET 192.168.10.0/24), or you may want to specify multiple ranges (var HOME_NET 192.168.10.0/24,10.0.2.0/24). In our case, we will look at just our local network: var HOME_NET 192.168.10.0/24 Likewise, we need to specify what is considered the external network. For most purposes, we want any IP address that is not a part of our specified home network to be considered as external. So we will place a comment on the line that reads var EXTERNAL_NET any and uncomment the line that says var EXTERNAL_NET !$HOME_NET: #var EXTERNAL_NET any var External_NET !$HOME_NET The screenshot represents the two lines that you need to alter to match the changes mentioned in this step. To view an extended list of Snort commands, please visit the Snort Users Manual at http://www.snort.org/assets/166/ snort_manual.pdf. Recursive directory encryption/decryption Encryption is a method of transforming data into a format that cannot be read by other users. Decryption is the method of transforming data back into a format that is readable. The benefit of encrypting your data is that even if the data is stolen, without the correct decryptor, it's unusable by the stealing party. You have the ability, depending on the program that you use, to encrypt individual files, folders, or entire hard drives. In this recipe, we will use gpgdir to perform recursive directory encryption and decryption. An advantage of using gpgdir is that it has the ability to not only encrypt a folder, but also all subfolders and files contained within our main folder. This will save you a lot of time and effort! Getting ready To complete this recipe, you must have gpgdir installed on your BackTrack version. How to do it... In order to use gpgdir, you must have it installed. If you have not installed it before, use the following instructions to install it: Open a terminal window and make a new directory under the root filesystem: mkdir /sourcecode Change your directory to the sourcecode directory: cd /sourcecode Next, we will use Wget to download the gpgdir application and its public key: wget http://cipherdyne.org/gpgdir/download/gpgdir- 1.9.5.tar.bz2 Next we download the signature file: wget http://cipherdyne.org/gpgdir/download/gpgdir- 1.9.5.tar.bz2.asc Next we download the public key file: Now we need to verify the package: gpg --import public_key gpg --verify gpgdir-1.9.5.tar.bz2.asc Next we untar gpgdir, switch to its directory, and complete the installation: tar xfj gpgdir-1.9.5.tar.bz2 cd gpgdir-1.9.5 ./install.pl The first time you run gpgdir, a new file will be created in your root directory (assuming root is the user you are using under BackTrack). The file is called ./ gpgdirrc. To start the creation of the file, type the following command: gpgdir Finally, we need to edit the gpgdirrc file and remove the comments from the default_key variable: vi /root/.gpgdirrc Now that you have gpgdir installed, let's use it to perform recursive directory encryption and decryption: Open a terminal window and create a directory for us to encrypt: mkdir /encrypted_directory Add files to the directory. You can add as many files as you would like using the Linux copy command cp. Now, we will use gpgdir to encrypt the directory: gpgdir -e /encrypted_directory At the prompt, enter your password. This is the password associated with your key file. To decrypt the directory with gpgdir, type the following command: gpgdir -d /encrypted_directory How it works… In this recipe, we used gpgdir to recursively encrypt a directory and to subsequently decrypt it. We began the recipe by installing gpgdir and editing its configuration file. Once gpgdir has been installed, we have the ability to encrypt and decrypt directories. For more information on gpgdir, please visit its documentation website at http://cipherdyne.org/gpgdir/docs/. Scanning for signs of rootkits A rootkit is a malicious program designed to hide suspicious processes from detection and allow continued, often remote, access to a computer system. Rootkits can be installed using various methods including hiding executable code within web page links, downloaded software programs, or on media files and documents. In this recipe, we will utilize chkrootkit to search for rootkits on our Windows or Linux system. Getting ready In order to scan for a rootkit, you can either use your BackTrack installation, log in to a compromised virtual machine remotely, or mount the BackTrack 5 R3 DVD on a computer system to which you have physical access. How to do it... Let's begin exploring chkrootkit by navigating to it from the BackTrack menu: Navigate to Applications | BackTrack | Forensics | Anti-Virus Forensics Tools | chkrootkit: Alternatively, you can enter the following commands to run chkrootkit: cd /pentest/forensics/chkrootkit ./chkrootkit chkrootkit will begin execution immediately, and you will be provided with an output on your screen as the checks are processed: How it works… In this recipe, we used chkrootkit to check for malware, Trojans, and rootkits on our localhost. chkrookit is a very effective scanner that can be used to determine if our system has been attacked. It's also useful when BackTrack is loaded as a live DVD and used to scan a computer you think is infected by rootkits. There's more... Alternatively, you can run Rootkit Hunter (rkhunter) to find rootkits on your system: Open a terminal window and run the following command to launch rkhunter: rkhunter --check At the end of the process, you will receive a summary listing the checks performed and their statistics: Useful alternative command options for chkrootkit The following is a list of useful commands to select when running chkrootkit: -h: Displays the help file -V: Displays the current running version of chkrootkit -l: Displays a list of available tests Useful alternative command options for rkhunter The following is a list of useful commands to select when running rkhunter: --update: Allows you to update the rkhunter database rkhunter --update --list: Displays a list of Perl modules, rootkits available for checking, and tests that will be performed rkhunter --list --sk: Allows you to skip pressing the Enter key after each test runs rkhunter --check --sk Entering rkhunter at a terminal window will display the help file: rkhunter
Read more
  • 0
  • 0
  • 5853

article-image-our-first-project-basic-thermometer
Packt
26 Feb 2013
24 min read
Save for later

Our First Project – A Basic Thermometer

Packt
26 Feb 2013
24 min read
(For more resources related to this topic, see here.) Building a thermometer A thermometer is a device used for recording temperatures and changes in temperatures. The origins of the thermometer go back several centuries, and the device has evolved over the years. Traditional thermometers are usually glass devices that measure these changes via a substance such as mercury, which rises in the glass tube and indicates a number in Fahrenheit or Celsius. The introduction of microelectronics has allowed us to build our own digital thermometers. This can be useful for checking the temperature in parts of your house such as the garage or monitoring the temperature in rooms where it can affect the contents, for example, a wine cellar. Our thermometer will return its readings to the Raspberry Pi and display them in the terminal window. Lets start by setting up the hardware for our thermometer. Setting up our hardware There are several components that you will need to use in this article. You can solder the items to your shield if you wish or use the breadboard if you plan to use the same components for the projects in the articles that follow. Alternatively, you may have decided to purchase an all-in-one unit that combines some of the following components into a single electronic unit. We will make the assumption that you have purchased separate electronic components and will discuss the process of setting these up. We recommend that you switch Raspberry Pi off while connecting the components, especially if you plan on soldering any of the items. If your device is switched on and you accidently spill hot solder onto an unintended area of the circuit board, this can short your device, damaging it. Soldering while switched off allows you to clean up any mistakes using the de-soldering tool. An introduction to resistors Let's quickly take a look at resistors and what exactly these are. A resistor is an electronic component with two connection points (known as terminals) that can be used to reduce the amount of electrical energy passing through a point in a circuit. This reduction in energy is known as resistance. Resistance is measured in Ohms (O). You can read more about how this is calculated at the Wikipedia link http://en.wikipedia.org/wiki/Ohm's_law. You will find resistors are usually classified into two groups, fixed resistors and variable resistors. The typical types of fixed resistor you will encounter are made of carbon film with the resistance property marked in colored bands, giving you the value in Ohms. Components falling into the variable resistance group are those with resistance properties that change when some other ambient property in their environment changes. Let's now examine the two types of resistors we will be using in our circuit — a thermistor and a 10K Ohm resistor. Thermistor A thermistor is an electronic component which, when included in a circuit, can be used to measure temperature. The device is a type of resistor that has the property whereby its resistance varies as the temperature changes. It can be found in a variety of devices, including thermostats and electronic thermometers. There are two categories of thermistors available, these being Negative Thermistor Coefficient(NTC)and Positive Thermistor Coefficient(PTC). The difference between them is that as the temperature increases the resistance decreases in the case of a NTC, or increases in the case of a PTC. There are two numerical properties that we are interested in with regards to using this device in our project. These are the resistance of the thermistor at room temperature (25 degrees Celsius) and the beta coefficient of the thermistor. The coefficient can be thought of as the amount the resistance changes by as the ambient temperature around the thermistor changes. When you purchase a thermistor, you should have been provided with a datasheet that lists these two values. If you are unsure of the resistance of your thermistor, you can always check it by hooking it up to a voltage detector and taking a reading at room temperature. For example, if you bought a 10K thermistor, you should expect a reading of around 10K Ohms. For this project, we recommend purchasing a 10K thermistor. 10K Ohm resistor A 10K Ohm resistor, unlike a thermistor, is designed to have a constant resistance regardless of temperature change. This type of device falls into the fixed resistor category. You can tell the value of a resistor by the colored bands located on its body. When you purchase resistors, you may find they come with a color-coding guide, otherwise you can check the chart on Wikipedia (http://en.wikipedia.org/wiki/Electronic_color_code#Resistor_color_coding) in order to ascertain what the value is. As part of the circuit we are building, you will need the 10K resistor in order to convert the changing resistance into a voltage that the analog pin on your Raspberry Pi to Arduino can understand. Wires For this project, you will require three wires. One will attach to the 5V pin on your shield, one to the ground, and finally, one to the analog 0 pin. In the wiring guide, we will be using red, black, and yellow wires. The red will connect to 5V pin, the black to ground, and the yellow to the analog 0 pin. Breadboard Finally, in order to connect our component, we will use the breadboard as we did when connecting up the LED. Connecting our components Setting up our components for the thermometer is a fairly easy task. Once again, at this point, there is no need to attempt any soldering if you plan on re-using the components. Follow these steps in order to connect up everything in the correct layout. Take the red wire and connect it from the 5V pin on the shield to the connect point on the bus strip corresponding to the supply voltage. There are often two bus strips on a breadboard. These can be found on either of the long sides of the board and often have a blue or red strip indicating supply voltage and ground. Next take the black wire and connect it from the ground pin to the ground on the breadboard. We are now going to hook up the resistor. Connect one pin of your 10K resistor to the supply voltage strip that your red wire is connected to and take the other end and connect it to a terminal strip. Terminal strips are the name given to the area located in the middle of the breadboard where you connect your electronic components. Now that the resistor is in place, our next task will be to connect the thermistor. Insert one leg/wire of the thermistor into the ground on the bus strip, and place the second leg into the same row as you placed the resistor. The thermistor and resistor are daisy-chained together with the supply voltage. This leaves us now with the final task, which is connecting up the analog pin to our daisy chain. Finally connect one end of your yellow wire from the analog 0 (A0) on your shield to the terminal strip you selected for the preceding components. Sanity check The setup of your circuit is now complete. However, before switching on your Raspberry Pi check that you have connected up everything correctly. You can compare your setup to the following diagram: Our thermometer circuit is now complete, and you can now boot up your Raspberry Pi. Of course, without any software to return readings to the screen, the circuit is little more than a combination of electronic components! So let's get started on the software portion of our project. Software for our thermometer Now that we have the hardware for our thermometer, we will need to write some code that is capable of converting the values returned from the thermistor into a readable temperature in Celsius and Fahrenheit. First up, we are going to look at a new code editing application. This IDE allows you to develop code in the Raspberry Pi X Window System environment and compile the code via a Makefile. We will start by looking at the Geany IDE. Geany IDE Geany is a lightweight Linux integrated development environment. It can be installed onto Raspbian and then used for writing code in the Arduino/C++ programming language. An added benefit of using this IDE is that we can set up a custom Makefile with the commands we have been using to compile arduPi-based projects. By combining the Makefile and Geany, we have an IDE that mimics the functionality we would use in the Arduino IDE, but with the added benefit we can save files without renaming them and compile our applications with one click. Installing the IDE We are going to use the apt-get tool to install Geany on to your Raspberry Pi. Start off with loading up your Terminal window. From the prompt, run the following command: sudo apt-get install geany You'll get the prompt alerting you to the fact that Geany will take up a certain amount of disk space. You can accept the prompt by selecting Y. Once complete, you will now see Geany located under the Programming menu option. Select the Geany icon from the previous menu to load the application. Once loaded, you will be presented with a code-editing interface. Along the top of the screen, you can find a standard toolbar. This includes the File menu where you can open and save files you are working on, and menus for Edit, Search, View, Document, Project, Build, Tools, and Help. The left-hand side of the screen contains a window that has a number of features including allowing you to jump to a function when you are editing your code. The bottom panel on the screen contains information about your application when you compile it. This is useful when debugging your code, as error messages will be displayed here. Geany has an extensive number of features. You can find a comprehensive guide to the IDE at the Geany website http://www.geany.org/. For our application development at this stage, we are only interested in creating a new file, opening a file, saving a file, and compiling a file. The options we need are located under the File menu item and the Build menu item. Feel free though to explore the IDE and get comfortable with it. In order to use the make option for compiling our application under the Build menu, we need to create a Makefile — we will now take a look at how to achieve this. An introduction to Makefiles The next tool we are going to use is the Makefile. A Makefile is executed by the Linux command make. Make is a command-line utility that allows you to compile executable files by storing the parameters into a Makefile and then calling it as needed. This method allows us to store common compilation directives and re-use them without having to type out the command each time. As you are familiar with, we have used the following command in order to compile our LED example: g++ -lrt -lpthread blink_test.cpp arduPi.o -o blink_test Using a Makefile, we could store this and then execute it when located in the same directory as the files using a simpler command. make We can try out creating a Makefile using the code. Load up Geany from the programming menu if you don't currently have it open. If you don't have a new document open, create a new one from the File menu. Now add the following lines to Blink_test/Makefile, making sure to tab the second line once: Blink: arduPi.o g++ -lrt -lpthread blink_test.cpp arduPi.o -o blink_test If you don't tab the second line containing the compilation instructions, then the Makefile won't run. Now that you have created the Makefile, we can save and run it with the following steps: From the File menu, select Save. From the Save dialog, navigate to the directory where you saved your blink_test.cpp and save the file with the title Makefile. Now open the blink_test.cpp file from the directory where you saved your Makefile. We can test our Makefile by selecting the Build option from the menu and selecting Make. In the panel at the bottom of the IDE, you will see a message indicating that the Makefile was executed successfully. Now from the Terminal window, navigate to the directory containing your blink_test project. Located in this directory, you will find your freshly compiled blink_test file. If you still have your LED example at hand, hook it up to the shield and from the command line, you can run the application by typing the following command: ./blink_test The LED should start blinking. Hopefully, you can see from this example that integrating the Makefile into the IDE allows us to write code and compile it as we go in order to debug it. This will be very useful when you start to work on projects with greater complexity. Once we have written the code to record our temperature readings, we will re-visit the Makefile and create a custom one to build our thermometer application via Geany. Now that you have set up Geany and briefly looked at Makefiles, lets get started with writing our application. Thermometer code We will be using the arduPi library for writing our code as we did for the LED test. As well as using standard Arduino and C++ syntax, we are going to explore some calculations that are used to return the results we need. In order to convert the values we are collecting from our circuit and convert them into a readable temperature, we are going to need to use an equation that converts resistance into temperature. This equation is known as the Steinhart-Hart equation. The Steinhart-Hart equation models the resistance of our thermistor at different temperatures and can be coded into an application in order to display the temperature in Kelvin, Fahrenheit, and Celsius. We will use a simpler version of this in our program (called the B parameter equation) and can use the values from the datasheet provided with our thermistor in order to populate the constants that are needed to perform the calculations. For a simpler version of the equation, we only need to know the following values: The room temperature in Kelvin The co-efficient of our thermistor (should be on the data sheet) The thermistor resistance at room temperature We will use Geany to write our application, so if you don't have it open, start it up. Writing our application From the File menu in Geany, create a new blank file; this is where we are going to add our Arduino code. If you save the file now, then Geany's syntax highlighting will be triggered making the code easier to read. Open the File menu in Geany and select Save. In the Save dialog box, navigate to the arduPi directory and save your file with the name thermometer.cpp. We will use the arduPi_template.cpp as the base for our project and add our code into it. To start, we will add in the include statements for the libraries and headers we need, as well as define some constants that will be used in our application for storing key values. Add the following block of code to your empty file, thermometer.cpp, in Geany: //Include ArduPi library #include "arduPi.h" //Include the Math library #include <math.h> //Needed for Serial communication SerialPi Serial; //Needed for accessing GPIO (pinMode, digitalWrite, digitalRead, //I2C functions) WirePi Wire; //Needed for SPI SPIPi SPI; // Values need for Steinhart-Hart equation // and calculating resistance. #define TENKRESISTOR 10000 //our 10K resistor #define BETA 4000 // This is the Beta Coefficient of your thermistor #define THERMISTOR 10000 // The resistance of your thermistor at room //temperature #define ROOMTEMPK 298.15 //standard room temperature in Kelvin //(25 Celsius). // Number of readings to take // these will be averaged out to // get a more accurate reading // You can increase/decrease this as needed #define READINGS 7 You will recognize some of the preceding code from the arduPi template, as well as some custom code we have added. This custom code includes a reference to the Math library. The Math library in C++ contains a number of reusable complex mathematical functions that can be called and which would help us avoid writing these from scratch. As you will see later in the program, we have used the logarithm function log() when calculating the temperature in Kelvin. Following are a number of constants; we use the #define statement here to initialize them: TENKRESISTOR: This is the 10K Ohm resistor you added to the circuit board. As you can see, we have assigned the value of 10,000 to it. BETA: This is the beta-coefficient of your thermistor. THERMISTOR: The resistance of your thermometer at room temperature. ROOMTEMPK: The room temperature in Kelvin, this translates to 25 degrees Celsius. READINGS: We will take seven readings from the analog pin and average these out to try and get a more accurate reading. The values we have used previously are for a 10K thermistor with a co-efficient of 4000. These should be updated as necessary to reflect the thermistor you are using in your project. Now that we have defined our constants and included some libraries, we need to add the body of the program. From the arduPi_template.cpp file, we now include the main function that kicks our application off. /********************************************************* * IF YOUR ARDUINO CODE HAS OTHER FUNCTIONS APART FROM * * setup() AND loop() YOU MUST DECLARE THEM HERE * * *******************************************************/ /************************** * YOUR ARDUINO CODE HERE * * ************************/ int main (){ setup(); while(1){ loop(); } return (0); } Remember that you can use both // and /* */ for commenting your code. We have our reference to the setup() function and to the loop() function, so we can now declare these and include the necessary code. Below the main() function, add the following: void setup(void) { printf("Starting up thermometer \n"); Wire.begin(); } The setup() function prints out a message to the screen indicating that the program is starting and then calls Wire.begin(). This will allow us to interact with the analog pins. Next we are going to declare the loop function and define some variables that will be used within it. void loop(void) { float avResistance; float resistance; int combinedReadings[READINGS]; byte val0; byte val1; // Our temperature variables float kelvin; float fahrenheit; float celsius; int channelReading; float analogReadingArduino; As you can see in the preceding code snippet, we have declared a number of variables. These can be broken down into: Resistance readings: These are float avResistance, float resistance, and byte val0 and byte val1. The variables avResistance and resistance will be used during the program's execution for recording resistance calculations. The other two variables val0 and val1 are used to store the readings from analog 0 on the shield. Temperature calculations: The variables float kelvin, float fahrenheit, and float celsius as their names suggest are used for recording temperature in three common formats. After declaring these variables, we need to access our analog pin and start to read data from it. Copy the following code into your loop function: /******************* ADC mappings Pin Address 0 0xDC 1 0x9C 2 0xCC 3 0x8C 4 0xAC 5 0xEC 6 0xBC 7 0xFC *******************/ // 0xDC is our analog 0 pin Wire.beginTransmission(8); Wire.write(byte(0xDC)); Wire.endTransmission(); Here we have code that initializes the analog pin 0. The code comment contains the mappings between the pins and addresses so if you wish, you can run the thermistor off a different analog pin. We are using pin 0, so we can now start to take readings from it. To get the correct data, we need to take two readings of a byte each from the pin. We will do this using a for loop. The Raspberry Pi to Arduino shield does not support the analogRead() and analogWrite() functions from the Arduino programming language. Instead we need to use the Wire commands and addresses from the table provided in the comments for this code. Add the following for loop below your previous block of code: /* Grab the two bytes returned from the analog 0 pin, combine them and write the value to the combinedReadings array */ for(int r=0; r<READINGS; r++){ Wire.requestFrom(8,2); val0 = Wire.read(); val1 = Wire.read(); channelReading = int(val0)*16 + int(val1>>4); analogReadingArduino = channelReading * 1023 /4095; combinedReadings[r] = analogReadingArduino; delay(100); } Here we have a loop that grabs the data from the analog pin so we can process it. In the requestFrom() function, we pass in the declaration for the number of bytes we wish to have returned from the pin. Here we can see we have two — this is the second value in the function call. We will combine these values and then write them to an array; in total, we will do this seven times and then average out the value. You will notice we are applying a calculation on the two combined bytes. This calculation converts the values into a 10-bit Arduino resolution. The value you will see returned after this equation is the same as you would expect to get from the analogRead() function on an Arduino Uno if you had hooked up your circuit to it. After we have done this calculation, we assign the value to our array that stores each of the seven readings. Now that we have this value, we can calculate the average resistance. For this, we will use another for loop that iterates through our array of readings, combines them, and then divides them by the value we set in our READINGS constant. Here is the next for loop you will need to accomplish this: // Grab the average of our 7 readings // in order to get a more accurate value avResistance = 0; for (int r=0; r<READINGS; r++) { avResistance += combinedReadings[r]; } avResistance /= READINGS; So far, we have grabbed our readings and can now use a calculation to work out the resistance. For this, we will need our avResistance reading, the resistance value of our 10K resistor, and our thermistor's resistance at room temperature. Add the following code that performs this calculation: /* We can now calculate the resistance of the readings that have come back from analog 0 */ avResistance = (1023 / avResistance) - 1; avResistance = TENKRESISTOR / avResistance; resistance = avResistance / THERMISTOR; The next part of the program uses the resistance to calculate the temperature. This is the portion of code utilizing the simpler version of the Steinhart-hart equation. The result of this equation will be the ambient temperature in degrees Kelvin. Next add the following block of code: // Calculate the temperature in Kelvin kelvin = log(resistance); kelvin /= BETA; kelvin += 1.0 / ROOMTEMPK; kelvin = 1.0 / kelvin; printf("Temperature in K "); printf("%f \n",kelvin); So we have our temperature in degrees K and also have a printf statement that outputs this value to the screen. It would be nice to also have the temperature in two more common temperature formats, those being Celsius and Fahrenheit. These are simple calculations to perform. Let's start by adding the Celsius code. // Convert from Kelvin to Celsius celsius = kelvin -= 273.15; printf("Temperature in C "); printf("%f \n",celsius); Now that we have the temperature in degrees Celsius, we can print this to the screen. Using this value we can convert Celsius into Fahrenheit. // Convert from Celsius to Fahrenheit fahrenheit = (celsius * 1.8) + 32; printf("Temperature in F "); printf("%f \n",fahrenheit); Great! So now we have the temperature being returned in three formats. Let's finish up the application by adding a delay of 3 seconds before the application takes another temperature reading and close off our loop() function. // Three second delay before taking our next // reading delay(3000); } So there we have it. This small application will use our circuit and return the temperature. We now need to compile the code so we can give it a test. Remember to save your code now so that the changes you have added are included in the thermometer.cpp file. Our next step is to create a Makefile for our thermometer application. If you saved the blink_test Makefile into the arduPi directory, you can re-use this or you can create a new file using the previous steps. Place the following code into your Makefile: Thermo: arduPi.o g++ -lrt -lpthread thermometer.cpp arduPi.o -o thermometer Save the file with the name Makefile. We can now compile and test our application. Compiling and testing When discussing Geany earlier, we demonstrated how to run the make command from inside the IDE. Now that we have our Makefile in place, we can test this out. From the Build menu, select Make. You should see the compilation pane at the bottom of the screen spring to life and providing there are no typos or errors in your code, a file called thermometer will be successful output. The thermometer file is our executable that we will run to view the temperature. From the terminal window, navigate to the arduPi directory and locate your thermometer file. This can be launched using the following command: sudo ./thermometer The application will now be executed and text similar to the following in the screenshot should be visible: Try changing the temperature by blowing on the thermometer, placing it in some cold water if safe to do so, or applying a hair dryer to it. You should see the temperature on the screen change. If you have a thermostat or similar in the room that logs the temperature, try comparing its value to that of your thermometer to see how accurate it is. You can run an application in the background by adding an & after the command, for example, sudo ./thermometer &. In the case of our application, it outputs to the screen, so if you attempt to use the same terminal window your typing will be interrupted! To kill an application running in the background, you can type fg to bring it to the foreground and then press Ctrl + C to cancel it. What if it doesn't work Providing you had no errors when compiling your code, then the chances are that one of your components is not connected properly, is connected to the wrong pin, or may be defective. Try double-checking your circuit to make sure everything is attached and hasn't become accidently dislodged. Also ensure that the components are wired up as suggested at the beginning of this article. If everything seems to be correct, you may have a faulty component. Try substituting each item one at a time in the circuit to see if it is a bad wire or faulty resistor. Up and running If you see your temperature being output successfully, then you are up and running! Congratulations, you now have a basic thermometer. This will form the basis for our next project, which is a thermostat. As you can see, this application is useful. However, returning the output to the screen isn't the best method, it would be better for example, if we could see the results via our web browser or an LCD screen. Now that we have a circuit and an application recording temperature, this opens up a wide variety of things we can do with the data, including logging it or using it to change the heat settings in our homes. This article should have whetted your appetite for bigger projects. Summary In this article, we learned how to wire up two new components — a thermistor and resistor. Our application taught us how to use these components to log a temperature reading, and we also became familiar with Makefiles and the Geany IDE. Resources for Article : Further resources on this subject: Folding @ Home on Ubuntu: Cancer Research Made Easy [Article] Using PVR with Raspbmc [Article] Using ChronoForms to add More Features to your Joomla! Form [Article]
Read more
  • 0
  • 0
  • 22318

article-image-core-net-recipes
Packt
26 Feb 2013
15 min read
Save for later

Core .NET Recipes

Packt
26 Feb 2013
15 min read
(For more resources related to this topic, see here.) Implementing the validation logic using the Repository pattern The Repository pattern abstracts out data-based validation logic. It is a common misconception that to implement the Repository pattern you require a relational database such as MS SQL Server as the backend. Any collection can be treated as a backend for a Repository pattern. The only point to keep in mind is that the business logic or validation logic must treat it as a database for saving, retrieving, and validating its data. In this recipe, we will see how to use a generic collection as backend and abstract out the validation logic for the same. The validation logic makes use of an entity that represents the data related to the user and a class that acts as the repository for the data allowing certain operations. In this case, the operation will include checking whether the user ID chosen by the user is unique or not. How to do it... The following steps will help check the uniqueness of a user ID that is chosen by the user: Launch Visual Studio .NET 2012. Create a new project of Class Library project type. Name it CookBook.Recipes.Core.CustomValidation. Add a folder to the project and set the folder name to DataModel. Add a new class and name it User.cs. Open the User class and create the following public properties: Property name Data type UserName String DateOfBirth DateTime Password String Use the automatic property functionality of .NET to create the properties. The final code of the User class will be as follows: namespace CookBook.Recipes.Core.CustomValidation { /// <summary> /// Contains details of the user being registered /// </summary> public class User { public string UserName { get; set; } public DateTime DateOfBirth { get; set; } public string Password { get; set; } } } Next, let us create the repository. Add a new folder and name it Repository. Add an interface to the Repository folder and name it IRepository.cs. The interface will be similar to the following code snippet: public interface IRepository { } Open the IRepository interface and add the following methods: Name Description Parameter(s) Return Type AddUser Adds a new user User object Void IsUsernameUnique Determines whether the username is already taken or not string Boolean After adding the methods, IRepository will look like the following code: namespace CookBook.Recipes.Core.CustomValidation { public interface IRepository { void AddUser(User user); bool IsUsernameUnique(string userName); } } Next, let us implement IRepository. Create a new class in the Repository folder and name it MockRepository. Make the MockRepository class implement IRepository. The code will be as follows: namespace CookBook.Recipes.Core.Data.Repository { public class MockRepository:IRepository { #region IRepository Members /// <summary> /// Adds a new user to the collection /// </summary> /// <param name="user"></param> public void AddUser(User user) { } /// <summary> /// Checks whether a user with the username already ///exists /// </summary> /// <param name="userName"></param> /// <returns></returns> public bool IsUsernameUnique(string userName) { } #endregion } } Now, add a private variable of type List<Users> in the MockRepository class. Name it _users. It will hold the registered users. It is a static variable so that it can hold usernames across multiple instantiations. Add a constructor to the class. Then initialize the _users list and add two users to the list: public class MockRepository:IRepository { #region Variables Private static List<User> _users; #endregion public MockRepository() { _users = new List<User>(); _users.Add(new User() { UserName = "wayne27", DateOfBirth = new DateTime(1950, 9, 27), Password = "knight" }); DateOfBirth = new DateTime(1955, 9, 27), Password = "justice" }); } #region IRepository Members /// <summary> /// Adds a new user to the collection /// </summary> /// <param name="user"></param> public void AddUser(User user) { } /// <summary> /// Checks whether a user with the username already exists /// </summary> /// <param name="userName"></param> /// <returns></returns> public bool IsUsernameUnique(string userName) { } #endregion } Now let us add the code to check whether the username is unique. Add the following statements to the IsUsernameUnique method: bool exists = _users.Exists(u=>u.UserName==userName); return !exists; The method turns out to be as follows: public bool IsUsernameUnique(string userName) { bool exists = _users.Exists(u=>u.UserName==userName); return !exists; } Modify the AddUser method so that it looks as follows: public void AddUser(User user) { _users.Add(user); } How it works... The core of the validation logic lies in the IsUsernameUnique method of the MockRespository class. The reason to place the logic in a different class rather than in the attribute itself was to decouple the attribute from the logic to be validated. It is also an attempt to make it future-proof. In other words, tomorrow, if we want to test the username against a list generated from an XML file, we don't have to modify the attribute. We will just change how IsUsernameUnique works and it will be reflected in the attribute. Also, creating a Plain Old CLR Object (POCO) to hold values entered by the user stops the validation logic code from directly accessing the source of input, that is, the Windows application. Coming back to the IsUsernameUnique method, it makes use of the predicate feature provided by .NET. Predicate allows us to loop over a collection and find a particular item. Predicate can be a static function, a delegate, or a lambda. In our case it is a lambda. bool exists = _users.Exists(u=>u.UserName==userName); In the previous statement, .NET loops over _users and passes the current item to u. We then make use of the item held by u to check whether its username is equal to the username entered by the user. The Exists method returns true if the username is already present. However, we want to know whether the username is unique. So we flip the value returned by Exists in the return statement, as follows: return !exists; Creating a custom validation attribute by extending the validation data annotation .NET provides data annotations as a part of the System.ComponentModel. DataAnnotation namespace. Data annotations are a set of attributes that provides out of the box validation, among other things. However, sometimes none of the in-built validations will suit your specific requirements. In such a scenario, you will have to create your own validation attribute. This recipe will tell you how to do that by extending the validation attribute. The attribute developed will check whether the supplied username is unique or not. We will make use of the validation logic implemented in the previous recipe to create a custom validation attribute named UniqueUserValidator. How to do it... The following steps will help you create a custom validation attribute to meet your specific requirements: Launch Visual Studio 2012. Open the CustomValidation solution. Add a reference to System.ComponentModel.DataAnnotations. Add a new class to the project and name it UniqueUserValidator. Add the following using statements: using System.ComponentModel.DataAnnotations; using CookBook.Recipes.Core.CustomValidation.MessageRepository; using CookBook.Recipes.Core.Data.Repository; Derive it from ValidationAttribute, which is a part of the System. ComponentModel.DataAnnotations namespace. In code, it would be as follows: namespace CookBook.Recipes.Core.CustomValidation { public class UniqueUserValidator:ValidationAttribute { } } Add a property of type IRepository to the class and name it Repository. Add a constructor and initialize Repository to an instance of MockRepository. Once the code is added, the class will be as follows: namespace CookBook.Recipes.Core.CustomValidation { public class UniqueUserValidator:ValidationAttribute { public IRepository Repository {get;set;} public UniqueUserValidator() { this.Repository = new MockRepository(); } } } Override the IsValid method of ValidationAttribute. Convert the object argument to string. Then call the IsUsernameUnique method of IRepository, pass the string value as a parameter, and return the result. After the modification, the code will be as follows: namespace CookBook.Recipes.Core.CustomValidation { public class UniqueUserValidator:ValidationAttribute { public IRepository Repository {get;set;} public UniqueUserValidator() { this.Repository = new MockRepository(); } public override bool IsValid(object value) { string valueToTest = Convert.ToString(value); return this.Repository.IsUsernameUnique(valueToTest); } } } We have completed the implementation of our custom validation attribute. Now let's test it out. Add a new Windows Forms Application project to the solution and name it CustomValidationApp. Add a reference to the System.ComponentModel.DataAnnotations and CustomValidation projects. Rename Form1.cs to Register.cs. Open Register.cs in the design mode. Add controls for username, date of birth, and password and also add two buttons to the form. The form should look like the following screenshot: Name the input control and button as given in the following table: Control Name Textbox txtUsername Button btnOK Since we are validating the User Name field, our main concern is with the textbox for the username and the OK button. I have left out the names of other controls for brevity. Switch to the code view mode. In the constructor, add event handlers for the Click event of btnOK as shown in the following code: public Register() { InitializeComponent(); this.btnOK.Click += new EventHandler(btnOK_Click); } void btnOK_Click(object sender, EventArgs e) { } Open the User class of the CookBook.Recipes.Core.CustomValidation project. Annotate the UserName property with UniqueUserValidator. After modification, the User class will be as follows: namespace CookBook.Recipes.Core.CustomValidation { /// <summary> /// Contains details of the user being registered /// </summary> public class User { [UniqueUserValidator(ErrorMessage="User name already exists")] public string UserName { get; set; } public DateTime DateOfBirth { get; set; } public string Password { get; set; } } } Go back to Register.cs in the code view mode. Add the following using statements: using System.ComponentModel; using System.ComponentModel.DataAnnotations; using CookBook.Recipes.Core.CustomValidation; using CookBook.Recipes.Core.Data.Repository; Add the following code to the event handler of btnOK: //create a new user User user = new User() { UserName = txtUsername.Text, DateOfBirth=dtpDob.Value }; //create a validation context for the user instance ValidationContext context = new ValidationContext(user, null, null); //holds the validation errors IList<ValidationResult> errors = new List<ValidationResult>(); if (!Validator.TryValidateObject(user, context, errors, true)) { foreach (ValidationResult result in errors) MessageBox.Show(result.ErrorMessage); } else { IRepository repository = new MockRepository(); repository.AddUser(user); MessageBox.Show("New user added"); } Hit F5 to run the application. In the textbox add a username, say, dreamwatcher. Click on OK. You will get a message box stating User has been added successfully Enter the same username again and hit the OK button. This time you will get a message saying User name already exists. This means our attribute is working as desired. Go to File | Save Solution As…, enter CustomValidation for Name, and click on OK. We will be making use of this solution in the next recipe. How it works... To understand how UniqueUserValidator works, we have to understand how it is implemented and how it is used/called. Let's start with how it is implemented. It extends ValidationAttribute. The ValidationAttribute class is the base class for all the validation-related attributes provided by data annotations. So the declaration is as follows: public class UniqueUserValidator:ValidationAttribute This allowed us to make use of the public and protected methods/attribute arguments of ValidationAttribute as if it is a part of our attribute. Next, we have a property of type IRepository, which gets initialized to an instance of MockRepository. We have used the interface-based approach so that the attribute will only need a minor change if we decide to test the username against a database table or list generated from a file. In such a scenario, we will just change the following statement: this.Repository = new MockRepository(); The previous statement will be changed to something such as the following: this.Repository = new DBRepository(); Next, we overrode the IsValid method. This is the method that gets called when we use UniqueUserValidator. The parameter of the IsValid method is an object. So we have to typecast it to string and call the IsUniqueUsername method of the Repository property. That is what the following statements accomplish: string valueToTest = Convert.ToString(value); return this.Repository.IsUsernameUnique(valueToTest); Now let us see how we used the validator. We did it by decorating the UserName property of the User class: [UniqueUserValidator(ErrorMessage="User name already exists")] public string UserName {get; set;} As I already mentioned, deriving from ValidatorAttribute helps us in using its properties as well. That's why we can use ErrorMessage even if we have not implemented it. Next, we have to tell .NET to use the attribute to validate the username that has been set. That is done by the following statements in the OK button's Click handler in the Register class: ValidationContext context = new ValidationContext(user, null, null); //holds the validation errors IList<ValidationResult> errors = new List<ValidationResult>(); if (!Validator.TryValidateObject(user, context, errors, true)) First, we instantiate an object of ValidationContext. Its main purpose is to set up the context in which validation will be performed. In our case the context is the User object. Next, we call the TryValidateObject method of the Validator class with the User object, the ValidationContext object, and a list to hold the errors. We also tell the method that we need to validate all properties of the User object by setting the last argument to true. That's how we invoke the validation routine provided by .NET. Using XML to generate a localized validation message In the last recipe you saw that we can pass error messages to be displayed to the validation attribute. However, by default, the attributes accept only a message in the English language. To display a localized custom message, it needs to be fetched from an external source such as an XML file or database. In this recipe, we will see how to use an XML file to act as a backend for localized messages. How to do it... The following steps will help you generate a localized validation message using XML: Open CustomValidation.sln in Visual Studio .NET 2012. Add an XML file to the CookBook.Recipes.Core.CustomValidation project. Name it Messages.xml. In the Properties window, set Build Action to Embedded Resource. Add the following to the Messages.xml file: <?xml version="1.0" encoding="utf-8" ?> <messages> <en> <message key="not_unique_user">User name is not unique</message> </en> <fr> <message key="not_unique_user">Nom d'utilisateur n'est pas unique</message> </fr> </messages> Add a folder to the CookBook.Recipes.Core.CustomValidation project. Name it MessageRepository. Add an interface to the MessageRepository folder and name it IMessageRepository. Add a method to the interface and name it GetMessages. It will have IDictionary<string,string> as a return type and will accept a string value as parameter. The interface will look like the following code: namespace CookBook.Recipes.Core.CustomValidation.MessageRepository { public interface IMessageRepository { IDictionary<string, string> GetMessages(string locale); } } Add a class to the MessageRespository folder. Name it XmlMessageRepository Add the following using statements: using System.Xml; Implement the IMessageRepository interface. The class will look like the following code once we implement the interface: namespace CookBook.Recipes.Core.CustomValidation.MessageRepository { public class XmlMessageRepository:IMessageRepository { #region IMessageRepository Members public IDictionary<string, string> GetMessages(string locale) { return null; } #endregion } } Modify GetMessages so that it looks like the following code: ublic IDictionary<string, string> GetMessages(string locale) { XmlDocument xDoc = new XmlDocument(); xDoc.Load(Assembly.GetExecutingAssembly().GetManifestResourceS tream("CustomValidation.Messages.xml")); XmlNodeList resources = xDoc.SelectNodes("messages/"+locale+"/ message"); SortedDictionary<string, string> dictionary = new SortedDictionary<string, string>(); foreach (XmlNode node in resources) { dictionary.Add(node.Attributes["key"].Value, node. InnerText); } return dictionary; } Next let us see how to modify UniqueUserValidator so that it can localize the error message. How it works... The Messages.xml file and the GetMessages method of XmlMessageRespository form the core of the logic to generate a locale-specific message. Message.xml contains the key to the message within the locale tag. We have created the locale tag using the two-letter ISO name of a locale. So, for English it is <en></en> and for French it is <fr></fr>. Each locale tag contains a message tag. The key attribute of the tag will have the key that will tell us which message tag contains the error message. So our code will be as follows: <message key="not_unique_user">User name is not unique</message> not_unique_user is the key to the User is not unique error message. In the GetMessages method, we first load the XML file. Since the file has been set as an embedded resource, we read it as a resource. To do so, we first got the executing assembly, that is, CustomValidation. Then we called GetManifestResourceAsStream and passed the qualified name of the resource, which in this case is CustomValidation.Messages.xml. That is what we achieved in the following statement: xDoc.Load(Assembly.GetExecutingAssembly().GetManifestResourceStream( "CustomValidation.Messages.xml")); Then we constructed an XPath to the message tag using the locale passed as the parameter. Using the XPath query/expression we got the following message nodes: XmlNodeList resources = xDoc.SelectNodes("messages/"+locale+"/ message"); After getting the node list, we looped over it to construct a dictionary. The value of the key attribute of the node became the key of the dictionary. And the value of the node became the corresponding value in the dictionary, as is evident from the following code: SortedDictionary<string, string> dictionary = new SortedDictionary<string, string>(); foreach (XmlNode node in resources) { dictionary.Add(node.Attributes["key"].Value, node.InnerText); } The dictionary was then returned by the method. Next, let's understand how this dictionary is used by UniqueUserValidator.
Read more
  • 0
  • 0
  • 2059

article-image-article-constructing-and-evaluating-your-design-solution
Packt
25 Feb 2013
9 min read
Save for later

Constructing and Evaluating Your Design Solution

Packt
25 Feb 2013
9 min read
(For more resources related to this topic, see here.) For constructing visualizations, technology matters The importance of being able to rationalize options has been a central theme of this book. As we reach the final stage of this journey and we are faced with the challenge of building our visualization solution, the keyword is, once again, choice. The intention of this book has been to focus on offering a handy strategy to help you work through the many design issues and decisions you're faced with. Up to now discussions about issues relating to technology and technical capability have been kept to a minimum in order to elevate the importance of the preparatory and conceptual stages. You have to work through these challenges regardless of what tools or skills you have. However, it is fair to say that to truly master data visualization design, it is inevitable that you will need to achieve technical literacy across a number of different applications and environments. All advanced designers need to be able to rely on a symphony of different tools and capabilities for gathering data, handling, and analyzing it before presenting, and launching the visual design. While we may have great concepts and impressively creative ideas, without the means to convert these into built solutions they will ultimately remain unrealized. The following example, tracking 61 years of tornado activity in the US, demonstrates a project that would have involved a great amount of different analytical and design-based technical skills and would not have been possible without these: Image In contrast to most of the steps that we have covered this far, the choices we make when it comes to producing the final data visualization design are more heavily influenced by capability and access to resources than necessarily the suitability of a given tool. This is something we covered earlier when identifying the key factors that shape what may or may not be possible to achieve. To many, the technology side of data visualization can be quite an overwhelming prospect—trying to harness and master the many different options available, knowing each one's relative strengths and weaknesses, identifying specific function and purpose, keeping on top of the latest developments and trends, and so on. Acquiring a broad technical skillset is clearly not easily accomplished. We touched on the different capability requirements of data visualization in article 2, Setting the Purpose and Identifying Key Factors, in the The "eight hats" of data visualization design section. This highlighted the importance of recognizing your strengths and weaknesses and where your skillset marries up with the varied and numerous demands of visualization design. In order to accommodate the absence of technical skills, in particular, you may need to find a way to collaborate with others or possibly scale down the level of your ambition. Visualization software, applications, and programs The scope of this book does not lend itself to provide a detailed dissection and evaluation of the many different possible tools and resources available for data visualization design. There are so many to choose from and it is a constantly evolving landscape—it feels like each new month sees an additional resource entering the fray. To help, you can find an up-to-date, curated list of the many technology options in this field by visiting http://www.visualisingdata.com/ index.php/resources/. Unlike other design disciplines, there is no single killer tool that does everything. To accommodate the agility of different technical solutions required in this field we have to be prepared to develop a portfolio of capabilities. What follows is a selection of just some of the most common, most useful, and most accessible options for you to consider utilizing and developing experience with. The tools presented have been classified to help you understand their primary purpose or function. Charting and statistical analysis tools This category covers some of the main charting productivity tools and the more effective visual analytics or Business Intelligence (BI) applications that offer powerful visualization capabilities. Microsoft Excel (http://office.microsoft.com/en-gb/excel/) is ubiquitous and has been a staple diet for many of us number crunchers for most of our working lives. Within the data visualization world, Excel's charting capabilities are somewhat derided largely down to the terrible default settings and the range of bad-practice charting functions it enables. (3D cone charts, anyone? No, thank you.) However, Excel does allow you to do much more than you would expect and, when fully exploited, it can prove to be quite a valuable ally. With experience and know-how, you can control and refine many chart properties and you will find that most of your basic charting requirements are met, certainly those that you might associate more with a pragmatic or analytical tone. Image Excel can also be used to serve up chart images for exporting to other applications (such as Illustrator, see later). Search online for the work of Jorge Camoes ( http://www.excelcharts.com/blog/), Jon Peltier (http://peltiertech.com/), and Chandoo (http://chandoo.org/) and you'll find some excellent visualization examples produced in Excel. Tableau (http://www.tableausoftware.com/) is a very powerful and rapid visual analytics application that allows you to potentially connect up millions of records from a range of origins and formats. From there you can quickly construct good practice charts and dashboards to visually explore and present your data. It is available as a licensed desktop or server version as well as a free-to-use public version. Tableau is particularly valuable when it comes to the important stage of data familiarization. When you want to quickly discover the properties, the shapes and quality of your data, Tableau is a great solution. It also enables you to create embeddable interactive visualizations and, like Excel, lets you export charts as images for use in other applications. Image There are many excellent Tableau practitioners out there whose work you should check out, such as Craig Bloodworth (http://www.theinformationlab.co.uk/ blog/), Jérôme Cukier (http://www.jeromecukier.net/), and Ben Jones (http://dataremixed.com/), among many others. While the overall landscape of BI is patchy in terms of its visualization quality, you will find some good additional solutions such as QlikView (http://www.qlikview.com/uk), TIBCO Spotfire (http://spotfire.tibco.com/), Grapheur (http://grapheur. com/), and Panopticon (http://www.panopticon.com/). You will also find that there are many chart production tools available online. Google has created a number of different ways to create visualizations through its Chart Tools (https://developers.google.com/chart/) and Visualization API (https://developers.google.com/chart/interactive/docs/reference) environments. While you can exploit these tools without the need for programming skills, the API platforms do enable developers to enhance the functional and design options themselves. Additionally, Google Fusion Tables (http://www.google.com/drive/start/ apps.html) offers a convenient method for publishing simple choropleth maps, timelines, and a variety of reasonably interactive charts. Image Other notable browser-based tools for analyzing data and creating embeddable or exportable data visualizations include DataWrapper (http://datawrapper.de/) and Polychart (http://polychart.com/). One of the first online offerings was Many Eyes, created by the IBM Visual Communications Lab in 2007, though ongoing support and development has lapsed. Many Eyes introduced many to Wordle (http://www.wordle.net/) a popular tool for visualizing the frequency of words used in text via "word clouds". Note, however, the novelty of this type of display has long since worn off for many people (especially please stop using it as your final PowerPoint slide in presentations!). Programming environments The ultimate capability in visualization design is to have complete control over the characteristics and behavior of every mark, property, and user-driven event on a chart or graph. The only way to fundamentally achieve this level of creative control is through the command of one or a range of programming languages. Until recent times one of the most important and popular options was Adobe Flash (http://www.adobe.com/uk/products/flash.html), a powerful and creative environment for animated and multimedia designs. Flash was behind many prominent interactive visualization designs in the field. However, Apple's decision to not support Flash on its mobile platforms effectively signaled the beginning of the end. Subsequently, most contemporary visualization programmers are focusing their developments on a range of powerful JavaScript environments and libraries. D3.js (http://d3js.org/) is the newest and coolest kid in town. Launched in 2011 from the Stanford Visualization Group that previously brought us Protovis (no longer in active development) this is a JavaScript library that has rapidly evolved into to the major player in interactive visualization terms. D3 enables you to take full creative control over your entire visualization design (all data representation and presentation features) to create incredibly smooth, expressive, and immersive interactive visualizations. Mike Bostock, the key creative force behind D3 and who now works at the New York Times, has an incredible portfolio of examples (http://bost.ocks.org/mike/) and you should also take a look at the work and tutorials provided by another D3 "hero", Scott Murray (http://alignedleft.com/). Image D3 and Flash are particularly popular (or have been popular, in the latter's case) because they are suitable for creating interactive projects to work in the browser. Over the past decade, Processing (http://processing.org/) has reigned as one of the most important solutions for creating powerful, generative, and animated visualizations that sit outside the browser, either as video, a separate application, or an installation. As an open source language it has built a huge following of creative programmers, designers, and artists look to optimize the potential of data representation and expression. There is a large and dynamic community of experts, authors, and tutorial writers that provide wonderful resources for anyone interested in picking up capabilities in this environment. There are countless additional JavaScript libraries and plugins that offer specialist capability, such as Paper.js (http://paperjs.org/) and Raphaël (http:// raphaeljs.com/), to really maximize your programming opportunities.
Read more
  • 0
  • 0
  • 2629
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-basic-editing
Packt
22 Feb 2013
6 min read
Save for later

Basic Editing

Packt
22 Feb 2013
6 min read
(For more resources related to this topic, see here.) AfterShot Pro has an internal queue of tools that will be used once we are ready to develop the photos. The order in which we use the tools to manipulate the RAW image files does not interfere with this queue. Nor does it make a difference with which tool you start your work. Just click on the File System tab in AfterShot Pro and navigate to one of your image folders. The thumbnail panel will then display all the images contained in the selected folder. Double-click on one of your photos and start working on your image. To start with editing I've selected a photo of one of my older models of trusty cameras. Here is the photo without any post processing. Pretty boring, right? So let's work on it. Basic adjustments Basic editing starts with the Basic Adjustments tool on the Standard tab. Here we will find all the controls for a quick edit. In case we are not satisfied with the results, we can always use the more detailed tools on the other tabs. However, for most images the Basic Adjustments tools will work nicely. The following two tools can make editing images a lot easier: AutoLevel: The AutoLevel tool will automatically adjust the black and white points of your image in a way that a fixed percent of the image will be pure black and pure white. You can control the tool with the two edit fields as shown in the preceding screenshot. The left-hand side field sets the percentage of the image to be pure black and the right-hand side field sets the percentage of the image to be pure white. Using 0,010 for both fields is a sensible starting point for editing. Using a higher percentage for the pure white will usually create unnecessary blown highlights and I can hardly imagine that anyone would want that. Perfectly Clear: The Perfectly Clear tool claims to automatically lighten your images optimally while at the same time maintaining true color and not introducing any clipping. With the Tint Max and Tint Min settings, it will also remove tints and improve contrast and sharpness. The Tint Off setting will lighten the image optimally while keeping the original colors. I've never been a fan of these tools because I like to have the colors as natural as possible, but perhaps it is just the right tool for your images. A word of warning, though. A lot of plugins for AfterShot Pro require you to turn off both of these tools to work properly. So if you experience strange behavior while using a plugin, check if the Perfectly Clear and AutoLevel tools are turned on. If they are, turn them off and see if the plugins now work correctly.   White Balance is the next tool in our basic editing workflow. We have the choice of As Shot, Custom Kelvin, Click White, and several other presets. Whatever we select, we can fine tune the image by either using the Temp slider by simply dragging it towards the right-hand side or the left-hand side or by entering a value directly into the input field. Having said that, make sure that when you use the Click White tool you click on an area of the image that has a neutral gray tone. Do not click on pure blacks or pure whites because that would set off the white balance totally. In the case of our example photo, the white balance looks good as it is. Let's continue editing the photo. We will discuss the other tools when need arises. Sharpening The Sharpening tool of AfterShot Pro is below standard. Nevertheless, you should know how it works. To turn on the Sharpening tool, simply tick the checkbox. You can change the amount of sharpening with the Amount slider and the sensitivity with the Sensitivity slider. Make sure that you use this tool with a 100% magnification view. Of course, you can also use the Sharpening slider of the Basic Adjustments tool. It corresponds directly to the Amount slider of the Sharpening tool. The Amount slider adjusts the overall sharpness of your image while the Sensitivity slider limits the portions of the image that are sharpened. The higher the amount, the sharper the image becomes. Take care though, because you can over-sharpen your image easily if you drag the slider too far. Sensitivity is just the opposite. The higher the sensitivity, the less of your image is affected by the unsharp mask filter that AfterShot Pro internally uses. So, you might need to raise the sensitivity when too much noise or other distractions become visible by raising the amount. The following screenshot shows a 100% crop after setting the Amount property to 120 and the Sensitivity property to 10. For comparison, only the right-hand side of the image is sharpened. The left-hand side of the image is straight out of the camera without any adjustments. We can use Layers for selective sharpening like this. As you can clearly see, it is easy to oversharpen if you are not careful. Also, artifacts appear quite quickly by using this tool. Cropping If you moved from slides to digital, like me, there might be good news for you. Remember with those 35 mm slides, when you didn't get the exact frame you wanted, you were in for a fiddling session with small masks or tape later. With digital images, correction of the frame is so much easier. Simply open the Cropping tool in AfterShot Pro. You have several choices to get the crop you want. For a quick crop, simply select one of the presets in the combobox, like 1.50 | 2:3 | 4x6 | 35mm as shown in the preceding screenshot. Then adjust the crop box by dragging the corners or the sides of the box. Both corners and sides will light up in red upon being dragged. As you can see, the Cropping tool features the Rule of Thirds indicators that makes cropping a breeze. In case there is no preset to your liking, simply select Custom. You can then draw your own selection box by clicking on the image and dragging the cursor over it. Also, you can enter a fixed Aspect or fixed Pixels in the dialog box. The arrow icon will change the box from portrait to landscape and vice versa. The lock icon is a bit tricky. As long as you choose Aspect, it is closed, thus giving you a locked aspect ratio for cropping. When you click on the icon, it changes to an open lock and at the same time the Aspect property switches to the Pixels property. Now you can crop to any size you like without having to care about a fixed aspect ratio. You can, however click on the lock again, thus closing it, and fix the selected pixel ratio. If you have entered your own settings, click on the plus icon to save these settings for later image edits. Once you are happy with your frame simply click on Done to close the dialog box and to complete the cropping.
Read more
  • 0
  • 0
  • 1130

article-image-yii-adding-users-and-user-management-your-site
Packt
21 Feb 2013
9 min read
Save for later

Yii: Adding Users and User Management to Your Site

Packt
21 Feb 2013
9 min read
(For more resources related to this topic, see here.) Mission Checklist This project assumes that you have a web development environment prepared. The files for this project include a Yii project directory with a database schema. To prepare for the project, carry out the following steps replacing the username lomeara with your own username: Copy the project files into your working directory. cp –r ~/Downloads/project_files/Chapter 3/project_files ~/projects/ch3 Make the directories that Yii uses web writeable. cd ~/projects/ch3/ sudo chown -R lomeara:www-data protected/runtime assets protected/models protected/controllers protected/views If you have a link for a previous project, remove it from the webroot directory. rm /opt/lampp/htdocs/cddb Create a link in the webroot directory to the copied directory. cd /opt/lampp/htdocs sudo ln -s ~/projects/ch3 cbdb Import the project into NetBeans (remember to set the project URL to http://localhost/cbdb) and configure for Yii development with PHPUnit. Create a database named cbdb and load the database schema (~/projects/ch3/ protected/data/schema.sql) into it. If you are not using the XAMPP stack or if your access to MySQL is password protected, you should review and update the Yii configuration file (in NetBeans it is ch3/Source Files/protected/config/main.php). Adding a User Object with CRUD As a foundation for our user management system, we will add a User table to the database and then use Gii to build a quick functional interface. Engage Thrusters Let's set the first building block by adding a User table containing the following information: A username Password hash Reference to a person entry for first name and last name In NetBeans, open a SQL Command window for the cbdb database and run the following command: CREATE TABLE 'user' ( 'id' int(10) unsigned NOT NULL AUTO_INCREMENT, 'username' varchar(20) NOT NULL, 'pwd_hash' char(34) NOT NULL, 'person_id' int(10) unsigned NOT NULL, PRIMARY KEY ('id'), UNIQUE KEY 'username' ('username'), CONSTRAINT 'userperson_ibfk_2' FOREIGN KEY ('person_id') REFERENCES 'person' ('id') ON DELETE CASCADE ) ENGINE=InnoDB; Open a web browser to the Gii URL http://localhost/cbdb/index.php/gii(the password configured in the sample code is yiibook) and use Gii to generate a model from the user table. Then, use Gii to generate CRUD from the user model. Back in NetBeans, add a link to the user index in your site's logged in menu (ch3 | Source Files | protected | views | layouts | main.php). It should look like this: } else { $this->widget('zii.widgets.CMenu',array( 'activeCssClass' => 'active', 'activateParents' => true, 'items'=>array( array('label'=>'Home', 'url'=>array('/site/index')), array('label'=>'Comic Books', 'url'=>array('/book'), 'items' => array( array('label'=>'Publishers', 'url'=>array('/publisher')), ) ), array('label'=>'Users', 'url'=>array('/user/index')), array('label'=>'Logout ('.Yii::app()->user- >name.')', 'url'=>array('/site/logout')) ), )); } ?> Right-click on the project name, run the site, and log in with the default username and password (admin/admin). You will see a menu that includes a link named Users. If you click on the Users link in the menu and then click on Create User, you will see a pretty awful-looking user-creation screen. We are going to fix that. First, we will update the user form to include fields for first name, last name, password, and repeat password. Edit ch3 | Source Files | protected | views | user | _form.php and add those fields. Start by changing all instances of $model to $user. Then, add a call to errorSummary on the person data under the errorSummary call on user. <?php echo $form->errorSummary($user); ?> <?php echo $form->errorSummary($person); ?> Add rows for first name and last name at the beginning of the form. <div class="row"> <?php echo $form->labelEx($person,'fname'); ?> <?php echo $form->textField($person,'fname',array ('size'=>20,'maxlength'=>20)); ?> <?php echo $form->error($person,'fname'); ?> </div> <div class="row"> <?php echo $form->labelEx($person,'lname'); ?> <?php echo $form->textField($person,'lname',array ('size'=>20,'maxlength'=>20)); ?> <?php echo $form->error($person,'lname'); ?> </div> Replace the pwd_hash row with the following two rows: <div class="row"> <?php echo $form->labelEx($user,'password'); ?> <?php echo $form->passwordField($user,'password',array ('size'=>20,'maxlength'=>64)); ?> <?php echo $form->error($user,'password'); ?> </div> <div class="row"> <?php echo $form->labelEx($user,'password_repeat'); ?> <?php echo $form->passwordField($user,'password_repeat',array ('size'=>20,'maxlength'=>64)); ?> <?php echo $form->error($user,'password_repeat'); ?> </div> Finally, remove the row for person_id. These changes are going to completely break the User create/update form for the time being. We want to capture the password data and ultimately make a hash out of it to store securely in the database. To collect the form inputs, we will add password fields to the User model that do not correspond to values in the database. Edit the User model ch3 | Source Files | protected | models | User.php and add two public variables to the class: class User extends CActiveRecord { public $password; public $password_repeat; In the same User model file, modify the attribute labels function to include labels for the new password fields. public function attributeLabels() { return array( 'id' => 'ID', 'username' => 'Username', 'password' => 'Password', 'password_repeat' => 'Password Repeat' ); } In the same User model file, update the rules function with the following rules: Require username Limit length of username and password Compare password with password repeat Accept only safe values for username and password We will come back to this and improve it, but for now, it should look like the following: public function rules() { // NOTE: you should only define rules for those attributes //that will receive user inputs. return array( array('username', 'required'), array('username', 'length', 'max'=>20), array('password', 'length', 'max'=>32), array('password', 'compare'), array('password_repeat', 'safe'), ); } In order to store the user's first and last name, we must change the Create action in the User controller ch3 | Source Files | protected | controllers | UserController. php to create a Person object in addition to a User object. Change the variable name $model to $user, and add an instance of the Person model. public function actionCreate() { $user=new User; $person=new Person; // Uncomment the following line if AJAX validation is //needed // $this->performAjaxValidation($user); if(isset($_POST['User'])) { $user->attributes=$_POST['User']; if($user->save()) $this->redirect(array('view','id'=>$user->id)); } $this->render('create',array( 'user'=>$user, 'person'=>$person, )); } Don't reload the create user page yet. First, update the last line of the User Create view ch3 | Source Files | protected | views | user | create.php to send a User object and a Person object. <?php echo $this->renderPartial('_form', array('user'=>$user, 'person' =>$person)); ?> Make a change to the attributeLabels function in the Person model (ch3 | Source Files | protected | models | Person.php) to display clearer labels for first name and last name. public function attributeLabels() { return array( 'id' => 'ID', 'fname' => 'First Name', 'lname' => 'Last Name', ); } The resulting user form should look like this: Looks pretty good, but if you try to submit the form, you will receive an error. To fix this, we will change the User Create action in the User controller ch3 | Source Files | protected | controllers | UserController.php to check and save both User and Person data. if(isset($_POST['User'], $_POST['Person'])) { $person->attributes=$_POST['Person']; if($person->save()) { $user->attributes=$_POST['User']; $user->person_id = $person->id; if($user->save()) $this->redirect(array('view','id'=>$user->id)); } } Great! Now you can create users, but if you try to edit a user entry, you see another error. This fix will require a couple of more changes. First, in the user controller ch3 | Source Files | protected | controllers | UserController.php, change the loadModel function to load the user model with its related person information: $model=User::model() ->with('person') ->findByPk((int)$id); Next, in the same file, change the actionUpdate function. Add a call to save the person data, if the user save succeeds: if($model->save()) { $model->person->attributes=$_POST['Person']; $model->person->save(); $this->redirect(array('view','id'=>$model->id)); } Then, in the user update view ch3 | Source Files | protected | views | user | update.php, add the person information to the form render. <?php echo $this->renderPartial('_form', array('user'=>$model, 'person' => $model->person)); ?> One more piece of user management housekeeping; try deleting a user. Look in the database for the user and the person info. Oops. Didn't clean up after itself, did it? Update the User controller ch3 | Source Files | protected | controllers | UserController.php once again. Change the call to delete in the User delete action: $this->loadModel($id)->person->delete(); Objective Complete - Mini Debriefing We have added a new object, User, to our site, and associated it with the Person object to capture the user's first and last name. Gii helped us get the basic structure of our user management function in place, and then we altered the model, view, and controller to bring the pieces together.
Read more
  • 0
  • 0
  • 10727

article-image-configuring-childbrowser-plugin
Packt
21 Feb 2013
4 min read
Save for later

Configuring the ChildBrowser plugin

Packt
21 Feb 2013
4 min read
(For more resources related to this topic, see here.)   Getting ready You should download the entire community PhoneGap plugin repository located at https://github.com/phonegap/phonegap-plugins. This will provide you nearly all the content necessary to use the plugins. How to do it… We're going to split this one up into what we have to do for each platform as the steps and environments are all quite different. Plugin configuration for iOS Let's look first at the steps necessary for installing the ChildBrowser plugin: Open the collection of plugins you downloaded and navigate to iOS/ChildBrowser. Drag ChildBrowser.bundle, ChildBrowserCommand.h, ChildBrowserCommand.m, ChildBrowserViewController.h, ChildBrowserViewController.m, and ChildBrowserViewController.xib into XCode to the Socializer/Plugins folder as shown in the following screenshot: At the prompt, make sure to copy the files (instead of linking to them), as shown in the following screenshot: Copy the ChildBrowser.js file to your www/plugins/iOS directory. You can do this in XCode or in Finder. Add the plugin to Cordova.plist in Socializer/Supporting Files in XCode: Find the Plugins row, and add a new entry as shown in the following table: ChildBrowserCommand String ChildBrowserCommand   This can be better represented by the following screenshot: There, that wasn't too bad, right? The final step is to update our www/index.html file to include this plugin for our app. Add the following lines after the line that is loading the "cordova-2.2.0-ios.js" script: <script type="application/javascript" charset="utf-8" src = "./plugins/iOS/ChildBrowser.js"></script> Plugin configuration for Android For Android, we'll be using the same plugin, located in the repository you should have already downloaded from GitHub (although it will be under another directory). Let's start by installing and configuring ChildBrowser using the following steps: Create a new package (File | New | Package) under your project's src folder. Name it as com.phonegap.plugins.childBrowser. Navigate to Android/ChildBrowser/src/com/phonegap/plugins/ childBrowser and drag the ChildBrowser.java file to the newly created package in Eclipse. Go to the res/xml folder in your project and open the config.xml file with the text editor (usually this is done by a right-click on the file, Open With | Text Editor). Add the following line at the bottom of the file, just above the </plugins> ending tag: <plugin name="ChildBrowser" value="com.phonegap.plugins.childBrowser.ChildBrowser"/> Navigate to the Android/ChildBrowser/www folder in the repository. Copy childbrowser.js to assets/www/plugins/Android. Copy the childbrowser folder to assets/www. (Copy the folder, not the contents. You should end up with assets/www/childbrowser when done.) The last step is to update our www/index_Android.html file by adding the following lines just below the portion that is loading the cordova-2.0.0-android.js file: <script type="application/javascript" charset="utf-8" src = "./plugins/Android/childbrowser.js"></script> That's it. Our plugin is correctly installed and configured for Android. There's more… There is one important detail to pay attention to—the plugin's readme file, if available. This file will often indicate the installation steps necessary, or any quirks that you might need to watch out for. The proper use of the plugin is also usually detailed. Unfortunately, some plugins don't come with instructions; at that point, the best thing to do is to try installing it in the normal fashion (as we've done earlier for the ChildBrowser plugin) and see if it works. The other thing to remember is that PhoneGap is an ongoing project. This means that there are plugins that are out-of-date (and indeed, some have had to be updated by the author for this book) and won't work correctly with the most recent versions of PhoneGap. You'll need to pay attention to the plugins so that you know which version it supports, and if it needs to be modified to work with a newer version of PhoneGap. Modifications usually aren't terribly difficult, but it does involve getting into the native code, so you may wish to ask the community (located at http://groups.google.com/group/phonegap) for any help in the modification. Summary In this article we saw the detailed installation and configuration of the ChildBrowser plugin. Moreover, we separately got acquainted with the process for both iOS and Android platforms. Finally, we saw how we can apply this knowledge to install other PhoneGap plugins and where we need to go in case we need any help. Resources for Article : Further resources on this subject: Creating Content in Social Networking using Joomla! [Article] iPhone: Issues Related to Calls, SMS, and Contacts [Article] Adding Geographic Capabilities via the GeoPlaces Theme [Article]
Read more
  • 0
  • 0
  • 2073

article-image-types-services-microsoft-dynamics-ax-2012
Packt
20 Feb 2013
8 min read
Save for later

Types of services in Microsoft Dynamics AX 2012

Packt
20 Feb 2013
8 min read
(For more resources related to this topic, see here.) Document services Document services use documents to represent business objects such as purchase and sales orders, customers, vendors, and so on. A document service is composed of the following components: Document query: This is a query that is created in the Application Object Tree (AOT) and contains all the tables that are related to the business object that you want to expose. Based on this query, the Document Service Generation Wizard can be used to generate the other artifacts that make up the document service. Table AxBC classes: An AxBC class is a wrapper for a table and contains business logic that is needed for Create, Read, Update, Delete (CRUD) operations. Document class: The purpose of the document class is to contain business logic that is associated with the creation and modification of the business entity itself. For example, the AxdCustomer class could contain logic to handle party information of a customer. Document service class: This is the actual service implementation class and extends the AifDocumentService class. This class implements the service operations that are published through the service contract. When creating document services, developers need to make sure that the business object is mapped correctly to the document query. The document services framework will handle all other things such as the serialization and deserialization of XML, date effectiveness, and so on. Document services can be deployed using the integration ports and all available adapters can be used. Custom services Custom services were already available in Microsoft Dynamics AX 2009, but support for Extended Data Types(EDTs) was limited, which resulted in developers having to provide custom serialization and deserialization logic. Microsoft Dynamics AX 2012 introduces the concept of attributes. Attributes provide a way to specify metadata about classes and methods. Two of these attributes are used when creating data contracts: the DataContractAttribute and DataMemberAttribute attributes. The DataContractAttribute attribute is used to define that a class is a data contract. The DataMemberAttribute attribute is added to methods of data contracts that represent data members that have to be exposed. This way of defining data contracts is very similar to other programming languages such as C#. Support for more complex data types such as collections and tables has been added so that these types can be serialized and deserialized without developers having to provide the logic themselves. In a typical custom service you will find the following components: Service contract: A service contract is an X++ class that contains methods with the SysEntryPointAttribute attribute. This identifies methods that will result in a service operation contract when the service is exposed. Data contracts: A data contract is an X++ class that is attributed with the DataContractAttribute attribute. It contains parameter methods that will be attributed as data members for each member variable that needs to be part of the data contract. Custom services can be deployed using the integration ports and any available adapter can be used. System services These services are new since the release of Microsoft Dynamics AX 2012. The main difference between these services and the previous two types is that they are not customizable and are not mapped to a query or X++ code. They are not customizable because they are written by Microsoft in managed code. One exception is the user session service, which is written in X++ code but is generally considered as a system service. There are three system services available for use in Microsoft Dynamics AX 2012: the query service, the metadata service, and the user session service. Query service The query service provides the means to run queries of the following three types: Static queries defined in the AOT. User-defined queries by using the QueryMetaData class in the service. Dynamic queries that are written in X++ classes. These classes need to extend the AIFQueryBuilder class. When queries are called by a service, the AOS authorization ensures that the caller has the correct permissions to retrieve the information. This means that unpermitted fields will be omitted from the query result. Furthermore, when joined data sources are not allowed to be used, the query call will result in an error that can be caught by the calling application. The resulting rows will be returned as an ADO.NET DataSet object. This can be very useful when you make use of controls in your application that can be bound to a DataSet object. The query service can be found at the following address: net.tcp://<hostname:port>/DynamicsAX/Services/QueryService Metadata service This system service can be used to retrieve metadata information about the AOT. Consumers of this service can get information such as which tables, classes, forms, and menu items are available in the system. An example usage of this service could be retrieving information about the AOT and using it in a dashboard application running on the Microsoft .NET Framework. The metadata service can be found at the following address: net.tcp://<hostname:port>/DynamicsAX/Services/MetaDataService User session service The third system service is the user session service. With this service you can retrieve information about the caller's user session. This information includes the user's default company, language, preferred calendar, time zone, and currency. The user session service can be found at the following address: net.tcp://<hostname:port>/DynamicsAX/Services/UserSessionService The right service for the right job Now that it is clear what types of services Microsoft Dynamics AX 2012 has to offer, the question arises as to when each type of service should be used. There is no simple answer for this due to the fact that every type has its strengths and weaknesses. Let us take a look at two factors that may help you make the right decision. Complexity Both document services and custom services can handle any business entity complexity. The document services framework parses the incoming XML and validates it against an XML Schema Definition(XSD) document. After validation, the framework calls the appropriate service action. Custom services on the other hand use the .NET XML Serializer and no validation of data is done. This means that any validations of the data in the data contract need to be written in code. Another advantage of document services over custom services is that the AxBC classes already contain a lot of the logic that is needed for CRUD operations. Flexibility Document services have service contracts that are tightly coupled with the AOT Query object. This means that when the query changes, the schema also changes. Data policies allow you to control which fields are exposed. When using custom services, this cannot be done by setup, but has to be done by attributing at design time. Custom services have the flexibility towards the service contract that the document services are lacking. Here the developer is in full control about what is in the contract and what is not. The operations, input parameters, and return types are all the responsibility of the developer. Another benefit in using custom services is the ability to use shared data contracts as parameters for your operations. Think of a company-wide software solution that involves the use of Microsoft Dynamics AX 2012 together with SharePoint and .NET applications that are all linked through BizTalk. You could opt to share data contracts to make sure that entities are the same for all of the components in the architecture. In that scenario, you're able to create a data contract in managed code and reference it in Microsoft Dynamics AX 2012. Then you can use that .NET data contract in your service operations as a parameter. There will probably be more factors that you will take into consideration to choose between the service types. But we can come to the following conclusion about when to use what type of service: Custom services: Custom services should be used when exposing entities that have a low complexity or data contracts that need to be shared between other applications. They are also ideal when custom logic needs to be exposed that may have nothing to do with data structures within Microsoft Dynamics AX. Document services: Document services should be used when exposing entities that have a high complexity and when validation of the data and structure would require a lot of work for developers to implement on their own. Query service: The query service should be used when only read operations are needed and there is no need for updates, inserts, or delete actions. It can be used when writing .NET Framework applications that leverage the data from Microsoft Dynamics AX returned as an ADO.NET DataSet. Metadata service: Use the metadata service when metadata information about objects in the AOT is required. User session service: The user session service should be used when user session-related information is required. Summary In this article, we went through the types of services in Microsoft Dynamics AX 2012. Resources for Article : Further resources on this subject: Setting up the Microsoft Dynamics GP System [Article] Overview of Microsoft Dynamics CRM 2011 [Article] Using Processes in Microsoft Dynamics CRM 2011 [Article]
Read more
  • 0
  • 0
  • 5476
article-image-so-what-spring-android
Packt
20 Feb 2013
3 min read
Save for later

So, what is Spring for Android?

Packt
20 Feb 2013
3 min read
(For more resources related to this topic, see here.) RestTemplate The RestTemplate module is a port of the Java-based REST client RestTemplate, which initially appeared in 2009 in Spring for MVC. Like the other Spring template counterparts (JdbcTemplate, JmsTemplate, and so on), its aim is to bring to Java developers (and thus Android developers) a high-level abstraction of lower-level Java API; in this case, it eases the development of HTTP clients. In its Android version, RestTemplate relies on the core Java HTTP facilities (HttpURLConnection) or the Apache HTTP Client. According to the Android device version you use to run your app, RestTemplate for Android can pick the most appropriate one for you. This is according to Android developers' recommendations. See http://android-developers.blogspot.ca/2011/09/androids-http-clients.html. This blog post explains why in certain cases Apache HTTP Client is preferred over HttpURLConnection. RestTemplate for Android also supports gzip compression and different message converters to convert your Java objects from and to JSON, XML, and so on. Auth/Spring Social The goal of the Spring Android Auth module is to let an Android app gain authorization to a web service provider using OAuth (Version 1 or 2). OAuth is probably the most popular authorization protocol (and it is worth mentioning that, it is an open standard) and is currently used by Facebook, Twitter, Google apps (and many others) to let third-party applications access users account. Spring for Android Auth module is based on several Spring libraries because it needs to securely (with cryptography) persist (via JDBC) a token obtained via HTTP; here is a list of the needed libraries for OAuth: Spring Security Crypto: To encrypt the token Spring Android OAuth: This extends Spring Security Crypto adding a dedicated encryptor for Android, and SQLite based persistence provider Spring Android Rest Template: To interact with the HTTP services Spring Social Core: The OAuth workflow abstraction While performing the OAuth workflow, we will also need the browser to take the user to the service provider authentication page, for example, the following is the Twitter OAuth authentication dialog: What Spring for Android is not SpringSource (the company behind Spring for Android) is very famous among Java developers. Their most popular product is the Spring Framework for Java which includes a dependency injection framework (also called an inversion of control framework). Spring for Android does not bring inversion of control to the Android platform. In its very first release (1.0.0.M1), Spring for Android brought a common logging facade for Android; the authors removed it in the next version. Summary In this article, we have learned that Spring for Android helps in easy development of Android applications. We learned the details about the important modules present in it and its functions. We also learnt about dependency injection framework in short and that Spring for Android does not bring inversion of control to the Android platform. Resources for Article : Further resources on this subject: Top 5 Must-have Android Applications [Article] Creating, Compiling, and Deploying Native Projects from the Android NDK [Article] Manifest Assurance: Security and Android Permissions for Flash [Article]
Read more
  • 0
  • 0
  • 10857

article-image-new-ipad-features-ios-6
Packt
20 Feb 2013
2 min read
Save for later

New iPad Features in iOS 6

Packt
20 Feb 2013
2 min read
(For more resources related to this topic, see here.) New iPad features and native applications We're going to identify some of the applications that come built-in to the new iPad. The applications designed by Apple for the iPad are Safari, Mail, Photos, FaceTime, Maps, Siri, Newsstand, Messages, Calendar, Reminders, Contacts, App Store, iTunes, Music, Videos, Notes, Camera, Photo Booth, Clock, Game Center, and Settings. Let's get started by exploring these applications. Getting ready Locate the Mail, Photos, App Store, iTunes, Music, and Settings apps For details on each app, visit http://www.apple.com/ipad/built-in-apps/ How to do it... These apps form the base of the iPad and by themselves can satisfy most of our media and communication needs. We'll delve deeper into each of the following apps in the upcoming recipes. Mail Photos App Store iTunes and Music Settings How it works... The applications can work together to provide a unifying experience. From the Photos app, we are able to share photos via the Mail application. Purchasing music in iTunes will allow us playback in our Music app. Ubiquity is what makes this device and its apps so useful. Summary This article gave us a brief overview of the application that illustrate the new iPad's features. Resources for Article : Further resources on this subject: Build iPhone, Android and iPad Applications using jQTouch [Article] Getting Started on UDK with iOS [Article] Interface Designing for Games in iOS [Article]
Read more
  • 0
  • 0
  • 8593

article-image-getting-started-bacula
Packt
20 Feb 2013
4 min read
Save for later

Getting started with Bacula

Packt
20 Feb 2013
4 min read
(For more resources related to this topic, see here.) Getting ready You will need root access to a BSD or Linux machine where you will be installing the Bacula server. This article is using Debian Linux 6.0 as an example. The machine is assumed to have an IP address of 10.10.1.100. How to do it... To install Bacula Director and Bacula Storage, perform the following steps: Log in to the target machine using SSH client or a physical console. Install the Bacula Director and Bacula Storage daemons plus the bconsole utility, using the package manager of your choice as follows (this example uses APT): $ apt-get install bacula-director-sqlite bacula-sd-sqlite baculaconsole Now, replace the contents of the /etc/bacula/bacula-dir.conf file with the following code: Director { Name = debian-dir DIRport = 9101 QueryFile = "/etc/bacula/scripts/query.sql" WorkingDirectory = "/var/lib/bacula" PidDirectory = "/var/run/bacula" Maximum Concurrent Jobs = 1 Password = "password-dir" DirAddress = 10.10.1.100 } Storage { Name = LocalStorage Address = 10.10.1.100 SDPort = 9103 Password = "password-sd" Device = FileStorage Media Type = File } Job { Name = DefaultJob Type = Backup Messages = Standard Pool = Default Client = DefaultClient Fileset = DefaultFileset Storage = LocalStorage } Client { Name = DefaultClient Address = 10.10.1.100 Password = "" Catalog = DefaultCatalog } Fileset { Name = DefaultFileset } Catalog { Name = DefaultCatalog dbname = "bacula"; dbuser = ""; dbpassword = "" } The highlighted lines contain information you might want to alter, such as passwords and network addresses. Replace the bacula-sd.conf file with a new one that has the following code: Storage { Name = LocalStorage SDPort = 9103 WorkingDirectory = "/var/lib/bacula" Pid Directory = "/var/run/bacula" Maximum Concurrent Jobs = 20 SDAddress = 10.10.1.100 } Director { Name = debian-dir Password = "password-sd" } Device { Name = FileStorage Media Type = File Archive Device = /tmp/test-backups LabelMedia = yes; Random Access = Yes; AutomaticMount = yes; RemovableMedia = no; AlwaysOpen = no; } Messages { Name = Standard director = debian-dir = all } And finally, the bconsole.conf file would look as follows: Director { Name = localhost-dir DIRport = 9101 address = 10.10.1.100 Password = "password-dir" } Note that appropriate passwords should match in both files. Now restart the daemons as follows so the new configuration is applied: $ /etc/init.d/bacula-director restart $ /etc/init.d/bacula-sd restart Create a directory for backup storage mentioned in the bacula-sd.conf file as follows: $ mkdir /tmp/test-backups Now you should be able to use the bconsole utility to inspect the status of Director and Storage using the status director and status storage commands as follows: $ bconsole Connecting to Director 10.10.1.100:9101 1000 OK: debian-dir Version: 5.0.2 (28 April 2010) Enter a period to cancel a command. *status director debian-dir Version: 5.0.2 (28 April 2010) i486-pc-linux-gnu debian squeeze/sid Daemon started 07-Jun-12 13:54, 0 Jobs run since started. Heap: heap=245,760 smbytes=48,038 max_bytes=48,940 bufs=109 max_ bufs=119 No Scheduled Jobs. ==== Running Jobs: No Jobs running. ==== *status storage Automatically selected Storage: LocalStorage Connecting to Storage daemon LocalStorage at 10.10.1.100:9103 LocalStorage Version: 5.0.2 ... Running Jobs: No Jobs running. Device status: Device "FileStorage" (/tmp/test-backups) is not open. * How it works... A typical Bacula system consists of three independently running daemons: Storage daemon (SD): This daemon receives backups from Director and stores them into the storage (files or tapes) File daemon (FD): This daemon collects the files from client machines and sends them to the Director Director daemon: This daemon performs job scheduling and negotiates data transfers between Storage and File daemons In this setup, we installed Director and Storage daemons on the same machine and configured a file-based storage at /tmp/test-backups in our filesystem. The bconsole utility is used to connect to the Director daemon, pass commands to it, and receive messages from it. When we requested the status of Storage with the status storage command, Director forwarded the request to Storage. Therefore, it's only important to have a direct connection from console to Director. Replace the sample passwords of Director, Storage and the bconsole utility. Each component can reside on a separate machine as long as connectivity between them is possible. Don't forget to always use fully qualified domain names or non-local IP addresses when specifying remote components. Summary In this article we learned to set up the simplest Bacula Director and Bacula Storage installations using the Bacula's bconsole utility. Resources for Article : Further resources on this subject: Backup in PostgreSQL 9 [Article] Recovery in PostgreSQL 9 [Article] Disaster Recovery for Hyper-V [Article]
Read more
  • 0
  • 0
  • 12600
article-image-getting-started-kinect-windows-sdk-programming
Packt
20 Feb 2013
12 min read
Save for later

Getting started with Kinect for Windows SDK Programming

Packt
20 Feb 2013
12 min read
(For more resources related to this topic, see here.) System requirements for the Kinect for Windows SDK While developing applications for any device using an SDK, compatibility plays a pivotal role. It is really important that your development environment must fulfill the following set of requirements before starting to work with the Kinect for Windows SDK. Downloading the example code You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support. and register to have the files e-mailed directly to you. Supported operating systems The Kinect for Windows SDK, as its name suggests, runs only on the Windows operating system. The following are the supported operating systems for development: Windows 7 Windows Embedded 7 Windows 8 The Kinect for Windows sensor will also work on Windows operating systems running in a virtual machine such as Microsoft HyperV, VMWare, and Parallels. System configuration The hardware requirements are not as stringent as the software requirements. It can be run on most of the hardware available in the market. The following are the minimum configurations required for development with Kinect for Windows: A 32- (x86) or 64-bit (x64) processor Dual core 2.66 GHz or faster processor Dedicated USB 2.0 bus 2 GB RAM The Kinect sensor It goes without saying, you need a Kinect sensor for your development. You can use the Kinect for Windows or the Kinect for Xbox sensor for your development. Before choosing a sensor for your development, make sure you are clear about the limitations of the Kinect for Xbox sensor over the Kinect for Windows sensor, in terms of features, API supports, and licensing mechanisms. The Kinect for Windows sensor By now, you are already familiar with the Kinect for Windows sensor and its different components. The Kinect for Windows sensor comes with an external power supply, which supplies the additional power, and a USB adapter to connect with the system. For the latest updates and availability of the Kinect for Windows sensor, you can refer to http://www.microsoft.com/en-us/kinectforwindows/site. The Kinect for Xbox sensor If you already have a Kinect sensor with your Xbox gaming console, you may use it for development. Similar to the Kinect for Windows sensor, you will require a separate power supply for the device so that it can power up the motor, camera, IR sensor, and so on. If you have bought a Kinect sensor with an Xbox as a bundle, you will need to buy the adapter / power supply separately. You can check out the external power supply adapter at http://www.microsoftstore.com. If you have bought only the Kinect for Xbox sensor, you will have everything that is required for a connection with a PC and external power cable. Development tools and software The following are the software that are required for development with Kinect SDK: Microsoft Visual Studio 2010 Express or higher editions of Visual Studio Microsoft .NET Framework 4.0 or higher Kinect for Windows SDK Kinect for Windows SDK uses the underlying speech capability of a Windows operating system to interact with the Kinect audio system. This will require Microsoft Speech Platform – Server Runtime, the Microsoft Speech Platform SDK, and a language pack to be installed in the system, and these will be installed along with the Kinect for Windows SDK. The system requirements for SDK may change with upcoming releases. Refer to http://www.microsoft.com/en-us/ kinectforwindows/. for the latest system requirements. Evaluation of the Kinect for Windows SDK   Though the Kinect for Xbox sensor has been in the market for quite some time, Kinect for Windows SDK is still fairly new in the developer paradigm, and it's evolving. The book is written on Kinect for Windows SDK v1.6. The Kinect for Windows SDK was first launched as a Beta 1 version in June 2011, and after a thunderous response from the developer community, the updated version of Kinect for Windows SDK Beta 2 version was launched in November 2011. Initially, both the SDK versions were a non-commercial release and were meant only for hobbyists. The first commercial version of Kinect for Windows SDK (v1.0) was launched in February 2012 along with a separate commercial hardware device. SDK v1.5 was released on May 2012 with bunches of new features, and the current version of Kinect for Windows SDK (v1.6) was launched in October 2012. The hardware hasn't changed since its first release. It was initially limited to only 12 countries across the globe. Now the new Kinect for Windows sensor is available in more than 40 countries. The current version of SDK also has the support of speech recognition for multiple languages.   Downloading the SDK and the Developer Toolkit The Kinect SDK and the Developer Toolkit are available for free and can be downloaded from http://www.microsoft.com/en-us/kinectforwindows/. The installer will automatically install the 64- or 32-bit version of SDK depending on your operating system. The Kinect for Windows Developer Toolkit is an additional installer that includes samples, tools, and other development extensions. The following diagram shows these components:   The main reason behind keeping SDK and Developer Toolkit in two different installers is to update the Developer Toolkit independently from the SDK. This will help to keep the toolkit and samples updated and distributed to the community without changing or updating the actual SDK version. The version of Kinect for Windows SDK and that for the Kinect for Windows Developer Toolkit might not be the same. Installing Kinect for Windows SDK Before running the installation, make sure of the following: You have uninstalled all the previous versions of Kinect for Windows SDK The Kinect sensor is not plugged into the USB port on the computer There are no Visual Studio instances currently running Start the installer, which will display the start screen as End User License Agreement. You need to read and accept this agreement to proceed with the installation. The following screenshot shows the license agreement:   Accept the agreement by selecting the checkbox and clicking on the Install option, which will do the rest of the job automatically. Before the installation, your computer may pop out the User Access Control (UAC) dialog, to get a confirmation from you that you are authorizing the installer to make changes in your computer. Once the installation is over, you will be notified along with an option for installing the Developer Toolkit, as shown in the next screenshot: Is it mandatory to uninstall the previous version of SDK before we install the new one? The upgrade will happen without any hassles if your current version is a non-Beta version. As a standard procedure, it is always recommended to uninstall the older SDK prior to installing the newer one, if your current version is a Beta version. Installing the Developer Toolkit If you didn't downloaded the Developer Toolkit installer earlier, you can click on the Download the Developer Toolkit option of the SDK setup wizard (refer to the previous screenshot); this will first download and then install the Developer Toolkit setup. If you have already downloaded the setup, you can close the current window and execute the standalone Toolkit installer. The installation process for Developer Toolkit is similar to the process for the SDK installer. Components installed by the SDK and the Developer Toolkit The Kinect for Windows SDK and Kinect for Windows Developer Toolkit install the drivers, assemblies, samples, and the documentation. To check which components are installed, you can navigate to the Install and Uninstall Programs section of Control Panel and search for Kinect. The following screenshot shows the list of components that are installed with the SDK and Toolkit installer: The default location for the SDK and Toolkit installation is %ProgramFiles%/Microsoft SDKs/Kinect. Kinect management service The Kinect for Windows SDK also installs Kinect Management, which is a Windows service that runs in the background while your PC communicates with the device. This service is responsible for the following tasks: Listening to the Kinect device for any status changes Interacting with the COM Server for any native support Managing the Kinect audio components by interacting with Windows audio drivers You can view this service by launching Services by navigating to Control Panel |Administrative Tools, or by typing Services.msc in the Run command. Is it necessary to install the Kinect SDK to end users' systems? The answer is No. When you install the Kinect for Windows SDK, it creates a Redist directory containing an installer that is designed to be deployed with Kinect applications, which install the runtime and drivers. This is the path where you can find the setup file after the SDK is installed: %ProgramFiles%/Microsoft SDKsKinectv1.6Redist KinectRuntime-v1.6-Setup.exe This can be used with your application deployment package, which will install only the runtime and necessary drivers. Connecting the sensor with the system Now that we have installed the SDK, we can plug the Kinect device into your PC. The very first time you plug the device into your system, you will notice the LED indicator of the Kinect sensor turning solid red and the system will start installing the drivers automatically. The default location of the driver is %Program Files%Microsoft Kinect DriversDrivers. The drivers will be loaded only after the installation of SDK is complete and it's a one-time job. This process also checks for the latest Windows updates on USB Drivers, so it is good to be connected to the Internet if you don't have the latest updates of Windows. The check marks in the dialog box shown in the next screenshot indicate successful driver software installation: When the drivers have finished loading and are loaded properly, the LED light on your Kinect sensor will turn solid green. This indicates that the device is functioning properly and can communicate with the PC as well. Verifying the installed drivers This is typically a troubleshooting procedure in case you encounter any problems. Also, the verification procedure will help you to understand how the device drivers are installed within your system. In order to verify that the drivers are installed correctly, open Control Panel and select Device Manager; then look for the Kinect for Windows node. You will find the Kinect for Windows Device option listed as shown in the next screenshot: Not able to view all the device components At some point of time, it may happen that you are able to view only the Kinect for Windows Device node (refer to the following screenshot). At this point of time, it looks as if the device is ready. However, a careful examination reveals a small hitch. Let's see whether you can figure it out or not! The Kinect device LED is on and Device Manager has also detected the device, which is absolutely fine, but we are still missing something here. The device is connected to the PC using the USB port, and the system prompt shows the device installed successfully—then where is the problem? The default USB port that is plugged into the system doesn't have the power capabilities required by the camera, sensor, and motor. At this point, if you plug it into an external power supplier and turn the power on, you will find all the driver nodes in Device Manager loaded automatically. This is one of the most common mistakes made by the developers. While working with Kinect SDK, make sure your Kinect device is connected with the computer using the USB port, and the external power adapter is plugged in and turned on. The next picture shows the Kinect sensor with USB connector and power adapter, and how they have been used: With the aid of the external power supply, the system will start searching for Windows updates for the USB components. Once everything is installed properly, the system will prompt you as shown in the next screenshot: All the check marks in the screenshot indicate that the corresponding components are ready to be used and the same components are also reflected in Device Manager. The messages prompting for the loading of drivers, and the prompts for the installation displaying during the loading of drivers, may vary depending upon the operating system you are using. You might also not receive any of them if the drivers are being loaded in the background. Detecting the loaded drivers in Device Manager Navigate to Control Panel | Device Manager, look for the Kinect for Windows node, and you will find the list of components detected. Refer to the next screenshot: The Kinect for Windows Audio Array Control option indicates the driver for the Kinect audio system whereas the Kinect for Windows Camera option controls the camera sensor. The Kinect for Windows Security Control option is used to check whether the device being used is a genuine Microsoft Kinect for Windows or not. In addition to appearing under the Kinect for Windows node, the Kinect for Windows USB Audio option should also appear under the Sound, Video and Game Controllers node, as shown in the next screenshot: Once the Kinect sensor is connected, you can identify the Kinect microphone like any other microphone connected to your PC in the Audio Device Manager section. Look at the next screenshot:  
Read more
  • 0
  • 0
  • 10553

article-image-getting-started-innodb
Packt
19 Feb 2013
9 min read
Save for later

Getting Started with InnoDB

Packt
19 Feb 2013
9 min read
(For more resources related to this topic, see here.) Basic features of InnoDB InnoDB is more than a fast disk-based relational database engine. It offers, at its core, the following features that separate it from other disk-based engines: MVCC ACID compliance Transaction support Row-level locking These features are responsible for providing what is known as Referential integrity; a core requirement for enterprise database applications. Referential integrity Referential integrity can be best thought of as the ability for the database application to store relational data in multiple tables with consistency. If a database lacks consistency between relational data, the data cannot be relied upon for applications. If, for example, an application stores financial transactions where monetary data is processed, referential integrity and consistency of transactional data is a key component. Financial data is not the only case where this is an important feature, as many applications store and process sensitive data that must be consistent Multiversion concurrency control A vital component is Multiversion concurrency control (MVCC), which is a control process used by databases to ensure that multiple concurrent connections can see and access consistent states of data over time. A common scenario relying on MVCC can be thought of as follows: data exists in a table and an application connection accesses that data, then a second connection accesses the same original data set while the first connection is making changes to it; since the first connection has not finalized its changes and committed its information we don't want the second connection to see the nonfinalized data. Thus two versions of the data exist at the same time—multiple versions—to allow the database to control the concurrent state of the data. MVCC also provides for the existence of point-in-time consistent views, where multiple versions of data are kept and are available for access based on their point-in-time existence. Transaction isolation Transaction support at the database level refers to the ability for units of work to be processed in separate units of execution from others. This isolation of data execution allows each database connection to manipulate, read, and write information at the same time without conflicting with each other. Transactions allow connections to operate on data on an all-or-nothing operation, so that if the transaction completes successfully it will be written to disk and recorded for upcoming transactions to then operate on. However, if the sequence of changes to the data in the transaction process do not complete then they can be rolled back, and no changes will be recorded to disk. This allows sequences of execution that contain multiple steps to fully succeed only if all of the changes complete, and to roll back any changed data to its original state if one or more of the sequence of changes in the transaction fail. This feature guarantees that the data remains consistent and referentially safe. ACID compliance An integral part of InnoDB is its ability to ensure that data is atomic, consistent, isolated, and durable; these features make up components of ACID compliance. Simply put, atomicity requires that if a transaction fails then the changes are rolled back and not committed. Consistency requires that each successfully executed transaction will move the database ahead in time from one state to the next in a consistent manner without errors or data integrity issues. Isolation defines that each transaction will see separate sets of data in time and not conflict with other transactional data access. Finally, the durability clause ensures that any data that has been committed in a successful transaction will be written to disk in its final state, without the risk of data loss from errors or system failure, and will then be available to transactions that come in the future. Locking characteristics Finally, InnoDB differs from other on-disk storage engines in that it offers row-level locking. This primarily differs, in the MySQL world, with the MyISAM storage engine which features table-level locking. Locking refers to an internal operation of the database that prohibits reading or writing of table data by connections if another is currently using that data. This prevents concurrent connections from causing data corruption or forcing data invalidation when data is in use. The primary difference between table- and row-level locking is that when a connection requests data from a table it can either lock the row of data being accessed or the whole table of data being accessed. For performance and concurrency benefits, row-level locking excels. System requirements and supported platforms InnoDB can be used on all platforms on which MySQL can be installed. These include: Linux: RPM, Deb, Tar BSDs: FreeBSD, OpenBSD, NetBSD Solaris and OpenSolaris / Illumos: SPARC + Intel IBM AIX HP-UX Mac OSX Windows 32 bit and 64 bit There are also custom ports of MySQL from the open source community for running MySQL on various embedded platforms and non-standard operating systems. Hardware-wise, MySQL and correspondingly InnoDB, will run on a wide variety of hardware, which at the time of this writing includes: Intel x86 32 bit AMD/Intel x 86_64 Intel Itanium IA-64 IBM Power architecture Apple's PPC PA-RISC 1.0 + 2.0 SPARC 32 + 64 bit Keep in mind when installing and configuring InnoDB, depending on the architecture in which it is installed, it will have certain options available and enabled that are not available on all platforms. In addition to the underlying hardware, the operating system will also determine whether certain configuration options are available and the range to which some variables can be set. One of the more decisively important differences to be considered while choosing an operating system for your database server is the manner in which the operating system and underlying filesystem handles write caching and write flushes to the disk storage subsystem. These operating system abilities can cause a dramatic difference in the performance of InnoDB, often to the order of 10 times the concurrency ability. When reading the MySQL documentation you may find that InnoDB has over fifty-eight configuration settings, more or less depending on the version, for tuning the performance and operational defaults. The majority of these default settings can be left alone for development and production server environments. However, there are several core settings that can affect great change, in either positive or negative directions depending on the application workload and hardware resource limits, with which every MySQL database administrator should be familiar and proficient. Keep in mind when setting values that some variables are considered dynamic while others are static; dynamic variables can be changed during runtime and do not require a process restart while static variables can only be changed prior to process start, so any changes made to static variables during runtime will only take effect upon the next restart of the database server process. Dynamic variables can be changed on the MySQL command line via the following command: mysql> SET GLOBAL [variable]=[value]; If a value is changed on the command line, it should also be updated in the global my.cnf configuration file so that the change is applied during each restart. MySQL memory allocation equations Before tuning any InnoDB configuration settings—memory buffers in particular—we need to understand how MySQL allocates memory to various areas of the application that handles RAM. There are two simple equations for referencing total memory usage that allocate memory based on incoming client connections: Per-thread buffers: Per-thread buffers, also called per-connection buffers since MySQL uses a separate thread for each connection, operate in contrast to global buffers in that per-thread buffers only allocate memory when a connection is made and in some cases will only allocate as much memory as the connection's workload requires, thus not necessarily utilizing the entire size of the allowable buffer. This memory utilization method is described in the MySQL manual as follows: Each client thread is associated with a connection buffer and a result buffer. Both begin with a size given by net_buffer_length but are dynamically enlarged up to max_allowed_packet bytes as needed. The result buffer shrinks to net_buffer_length after each SQL statement. Global buffers: Global buffers are allocated memory resources regardless of the number of connections being handled. These buffers request their memory requirements during the startup process and retain this reservation of resources until the server process has ended. When allocating memory to MySQL buffers we need to ensure that there is also enough RAM available for the operating system to perform its tasks and processes; in general it is a best practice to limit MySQL between 85 to 90 percent allocation of total system RAM. The memory utilization equations for each of the buffers is given as follows: Per-thread Buffer memory utilization equation: (read_buffer_size + read_rnd_buffer_size + sort_buffer_size + thread_stack + join_buffer_size + binlog_cache_size) * max_connections = total memory allocation for all connections, or MySQL Thread Buffers (MTB) Global Buffer memory utilization equation: innodb_buffer_pool_size + innodb_additional_mem_pool_size + innodb_ log_buffer_size + key_buffer_size + query_cache_size = total memory used by MySQL Global Buffers (MGB) Total memory allocation equation: MTB + MGB = Total Memory Used by MySQL If the total memory used by the combination of MTB and MGB is greater than 85 to 90 percent of the total system RAM then you may experience resource contention, a resource bottleneck, or in the worst case you will see memory pages swapping to on-disk resources (virtual memory) which results in performance degradation and, in some cases, process failure or connection timeouts. Therefore it is wise to check memory allocation via the equations mentioned previously before making changes to the memory buffers or increasing the value of max_connections to the database. More information about how MySQL manages memory and threads can be read about in the following pages of the MySQL documentation: http://dev.mysql.com/doc/refman/5.5/en/connection-threads.html http://dev.mysql.com/doc/refman/5.5/en/memory-use.html Summary This article provided a quick overview of the core terminology and basic features, system requirements, and a few memory allocation equations. Resources for Article : Further resources on this subject: Configuring MySQL [Article] Optimizing your MySQL Servers' performance using Indexes [Article] Indexing in MySQL Admin [Article]
Read more
  • 0
  • 0
  • 1891
Modal Close icon
Modal Close icon