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

7019 Articles
article-image-using-raspberry-pi-camera-module
Packt
06 Apr 2017
6 min read
Save for later

Using the Raspberry Pi Camera Module

Packt
06 Apr 2017
6 min read
This article by Shervin Emami, co-author of the book, Mastering OpenCV 3 - Second Edition, explains how to use the Raspberry Pi Camera Module for your Cartoonifier and Skin changer applications. While using a USB webcam on Raspberry Pi has the convenience of supporting identical behavior & code on desktop as on embedded device, you might consider using one of the official Raspberry Pi Camera Modules (referred to as the RPi Cams). They have some advantages and disadvantages over USB webcams: (For more resources related to this topic, see here.) RPi Cams uses the special MIPI CSI camera format, designed for smartphone cameras to use less power, smaller physical size, faster bandwidth, higher resolutions, higher framerates, and reduced latency, compared to USB. Most USB2.0 webcams can only deliver 640x480 or 1280x720 30 FPS video, since USB2.0 is too slow for anything higher (except for some expensive USB webcams that perform onboard video compression) and USB3.0 is still too expensive. Whereas smartphone cameras (including the RPi Cams) can often deliver 1920x1080 30 FPS or even Ultra HD / 4K resolutions. The RPi Cam v1 can in fact deliver up to 2592x1944 15 FPS or 1920x1080 30 FPS video even on a $5 Raspberry Pi Zero, thanks to the use of MIPI CSI for the camera and a compatible video processing ISP & GPU hardware inside the Raspberry Pi. The RPi Cam also supports 640x480 in 90 FPS mode (such as for slow-motion capture), and this is quite useful for real-time computer vision so you can see very small movements in each frame, rather than large movements that are harder to analyze. However the RPi Cam is a plain circuit board that is highly sensitive to electrical interference, static electricity or physical damage (simply touching the small orange flat cable with your finger can cause video interference or even permanently damage your camera!). The big flat white cable is far less sensitive but it is still very sensitive to electrical noise or physical damage. The RPi Cam comes with a very short 15cm cable. It's possible to buy third-party cables on eBay with lengths between 5cm to 1m, but cables 50cm or longer are less reliable, whereas USB webcams can use 2m to 5m cables and can be plugged into USB hubs or active extension cables for longer distances. There are currently several different RPi Cam models, notably the NoIR version that doesn't have an internal Infrared filter, therefore a NoIR camera can easily see in the dark (if you have an invisible Infrared light source), or see Infrared lasers or signals far clearer than regular cameras that include an Infrared filter inside them. There are also 2 different versions of RPi Cam (shown above): RPi Cam v1.3 and RPi Cam v2.1, where the v2.1 uses a wider angle lens with a Sony 8 Mega-Pixel sensor instead of a 5 Mega-Pixel OmniVision sensor, and has better support for motion in low lighting conditions, and adds support for 3240x2464 15 FPS video and potentially upto 120 FPS video at 720p. However, USB webcams come in thousands of different shapes & versions, making it easy to find specialized webcams such as waterproof or industrial-grade webcams, rather than requiring you to create your own custom housing for an RPi Cam. IP Cameras are also another option for a camera interface that can allow 1080p or higher resolution videos with Raspberry Pi, and IP cameras support not just very long cables, but potentially even work anywhere in the world using Internet. But IP cameras aren't quite as easy to interface with OpenCV as USB webcams or the RPi Cam. In the past, RPi Cams and the official drivers weren't directly compatible with OpenCV, you often used custom drivers and modified your code in order to grab frames from RPi Cams, but it's now possible to access an RPi Cam in OpenCV the exact same way as a USB Webcam! Thanks to recent improvements in the v4l2 drivers, once you load the v4l2 driver the RPi Cam will appear as file /dev/video0 or /dev/video1 like a regular USB webcam. So traditional OpenCV webcam code such as cv::VideoCapture(0) will be able to use it just like a webcam. Installing the Raspberry Pi Camera Module driver First let's temporarily load the v4l2 driver for the RPi Cam to make sure our camera is plugged in correctly: sudo modprobe bcm2835-v4l2 If the command failed (that is, it printed an error message to the console, or it froze, or the command returned a number beside 0), then perhaps your camera is not plugged in correctly. Shutdown then unplug power from your RPi and try attaching the flat white cable again, looking at photos on the Web to make sure it's plugged in the correct way around. If it is the correct way around, it's possible the cable wasn't fully inserted before you closed the locking tab on the RPi. Also check if you forgot to click Enable Camera when configuring your Raspberry Pi earlier, using the sudo raspi-config command. If the command worked (that is, the command returned 0 and no error was printed to the console), then we can make sure the v4l2 driver for the RPi Cam is always loaded on bootup, by adding it to the bottom of the /etc/modules file: sudo nano /etc/modules # Load the Raspberry Pi Camera Module v4l2 driver on bootup: bcm2835-v4l2 After you save the file and reboot your RPi, you should be able to run ls /dev/video* to see a list of cameras available on your RPi. If the RPi Cam is the only camera plugged into your board, you should see it as the default camera (/dev/video0), or if you also have a USB webcam plugged in then it will be either /dev/video0 or /dev/video1. Let's test the RPi Cam using the starter_video sample program: cd ~/opencv-3.*/samples/cpp DISPLAY=:0 ./starter_video 0 If it's showing the wrong camera, try DISPLAY=:0 ./starter_video 1. Now that we know the RPi Cam is working in OpenCV, let's try Cartoonifier! cd ~/Cartoonifier DISPLAY=:0 ./Cartoonifier 0 (or DISPLAY=:0 ./Cartoonifier 1 for the other camera). Resources for Article: Further resources on this subject: Video Surveillance, Background Modeling [article] Performance by Design [article] Getting started with Android Development [article]
Read more
  • 0
  • 0
  • 5865

article-image-ai-distilled-27-ai-breakthroughs-open-source-pioneers
Merlyn Shelley
24 Nov 2023
13 min read
Save for later

AI_Distilled #27: AI Breakthroughs & Open-Source Pioneers

Merlyn Shelley
24 Nov 2023
13 min read
Dive deeper into the world of AI innovation and stay ahead of the AI curve! Subscribe to our AI_Distilled newsletter for the latest insights. Don't miss out – sign up today!👋 Hello ,Welcome to another AI_Distilled! This edition brings you key stories on AI, ML, NLP, Gen AI, and more. Our mission is to keep you informed, empowering your skill advancement. Before we embark on the need-to-know updates, let’s take a moment to observe an important perspective from an industry leader. “We’re now seeing a major second wave…let’s acknowledge that without open source, how would AI have made the tremendous progress it has over the last decade” -Jensen Huang, NVIDIA CEO Amidst the uncertainty surrounding Sam Altman's removal and reinstatement at OpenAI, the open-source community emerges as a potential beneficiary. Also, as OpenAI pauses new signups for ChatGPT Plus, enterprises are anticipated to seek stability and long-term impact by turning to open-source AI models such as Llama, Mistral, Falcon, and MPT for their AI application development needs. Both proprietary and open-source models will play roles, but the latter's contributions are crucial for advancing AI technology's impact on work and life. In this week’s edition, we’ll talk about Google DeepMind unveiling an advanced AI music generation model and experiments, Meta releasing Emu Video and Emu Edit, major breakthroughs in generative AI research, Microsoft Ignite 2023 bringing new AI expansions and product announcements, and Galileo's Hallucination Index identifying GPT-4 as the best LLM for different use cases. We’ve also got you your fresh dose of AI secret knowledge and tutorials including how to implement emerging practices for society-centered AI, how to speed up and improve LLM output with skeleton-of-thought, getting started with Llama 2 in 5 steps, and how to build an AI assistant with real-time web access in 100 lines of code using Python and GPT-4. Also, don't forget to check our expert insights column, which covers the interesting concepts of data architecture from the book 'Modern Data Architecture on AWS'. It's a must-read!  Stay curious and gear up for an intellectually enriching experience!  📥 Feedback on the Weekly EditionHey folks!After the stunning OpenAI DevDay, many of us were eager to embark on creating our custom GPT magic. But let's chat about the recent hiccups: the pause on ChatGPT-4 new sign-ups and the shift or reformation in OpenAI's leadership. It's got us all wondering about the future of our handy tools. Quick question: Ever tried ChatGPT's Advanced Data Analysis? Now that it's temporarily on hold for new users, it's got us thinking, right? Share your take on these changes in the comments. Your thoughts count! We're turning the spotlight on you – some of the best insights will be featured in our next issue for our 38K-strong AI-focused community. Don't miss out on the chance to share your views! 🗨️✨ As a big thanks, get our bestselling "The Applied Artificial Intelligence Workshop" in PDF.   Let's make AI_Distilled even more awesome! 🚀 Jump on in! Share your thoughts and opinions here! Writer’s Credit: Special shout-out to Vidhu Jain for their valuable contribution to this week’s newsletter content!  Cheers,  Merlyn Shelley  Editor-in-Chief, Packt  SignUp | Advertise | Archives⚡ TechWave: AI/GPT News & Analysis🔳 Sam Altman Is Reinstated as OpenAI’s Chief Executive: OpenAI reinstated CEO Sam Altman, reversing his ouster amid a board shake-up. The revamped board, led by Bret Taylor, includes Lawrence Summers and Adam D'Angelo, with Microsoft's support. Negotiations involved concessions, including an independent investigation into Altman's leadership. Some outgoing members sought to curb Altman's power. Altman's removal sparked a campaign by allies and employees for his return. The board initially stood by its decision but ultimately reinstated Altman for a fresh start. 🔳 Google DeepMind Unveils Advanced AI Music Generation Model and Experiments: Google DeepMind introduces Lyria, an advanced AI music generation model, and collaborates with YouTube on two experiments, "Dream Track" and "Music AI tools," revolutionizing music creation. Lyria excels in maintaining musical continuity, while the experiments support artists and producers in crafting unique soundtracks and enhancing the creative process. 🔳 Meta Unveils Emu Video and Emu Edit: Advancements in Generative AI Research: Meta has unveiled two major advancements in generative AI: Emu Video, a text-to-video platform using diffusion models for high-quality content generation, and Emu Edit, an image editing tool for precise control. Human evaluations favor Emu Video over previous models, showcasing substantial progress in creative and effective generative AI tools. 🔳 Google's AI Search Feature Expands to 120+ Countries: Google's Search Generative Experience (SGE) has expanded to 120+ countries, offering generative AI summaries and language support for Spanish, Portuguese, Korean, and Indonesian. Users can ask follow-up questions and get interactive definitions. The update will initially roll out in the US before expanding globally, enhancing natural language interactions in search results. 🔳 Microsoft Ignite 2023 Brings New AI Expansions and Product Announcements: Microsoft's Ignite 2023 highlighted the company's deepened AI commitment, featuring Bing Chat's rebranding to Copilot, custom AI chips, and new AI tools like Copilot for Azure. Microsoft Teams will offer AI-driven home decoration and voice isolation. The company consolidated planning tools, introduced generative AI copyright protection, Windows AI Studio for local AI deployment, and Azure AI Speech for text-to-speech avatars. The event underscored Microsoft's emphasis on AI integration across its products and services. 🔳 Microsoft Emerges as Ultimate Winner in OpenAI Power Struggle: Microsoft emerged victorious in the OpenAI power struggle by hiring ousted CEO Sam Altman and key staff, including Greg Brockman, to lead a new advanced AI team. This strategic move solidifies Microsoft's dominance in the industry, positioning it as a major player in AI without acquiring OpenAI, valued at $86 billion. The recent turmoil at OpenAI has led to employee threats of quitting and joining Altman at Microsoft, potentially granting Microsoft access to significant AI talent. 🔳 Galileo's Hallucination Index Identifies GPT-4 As the Best LLM for Different Use Cases: San Francisco based Galileo has introduced a Hallucination Index to aid users in selecting the most reliable Large Language Models (LLMs) for specific tasks. Evaluating various LLMs, including Meta's Llama series, the index found GPT-4 excelled, and OpenAI's models consistently performed well, supporting trustworthy GenAI applications. 🔳 Microsoft Releases Orca 2: Small Language Models That Outperform Larger Ones: Orca 2, comprising 7 billion and 13 billion parameter models, excels in intricate reasoning tasks, surpassing larger counterparts. Developed by fine-tuning LLAMA 2 base models on tailored synthetic data, Orca 2 showcases advancements in smaller language model research, demonstrating adaptability across tasks like reasoning, grounding, and safety through post-training with carefully filtered synthetic data. 🔳 NVIDIA CEO Predicts Major Second Wave of AI: Jensen Huang predicts a significant AI surge, citing breakthroughs in language replicated in biology, manufacturing, and robotics, offering substantial opportunities for Europe. Praising France's AI leadership, he emphasizes the importance of region-specific AI systems reflecting cultural nuances and highlights the crucial role of data in regional AI growth. 🔮 Expert Insights from Packt Community Modern Data Architecture on AWS - By Behram Irani Challenges with on-premises data systems As data grew exponentially, so did the on-premises systems. However, visible cracks started to appear in the legacy way of architecting data and analytics use cases. The hardware that was used to process, store, and consume data had to be procured up-front, and then installed and configured before it was ready for use. So, there was operational overhead and risks associated with procuring the hardware, provisioning it, installing software, and maintaining the system all the time. Also, to accommodate for future data growth, people had to estimate additional capacity way in advance. The concept of hardware elasticity didn’t exist.The lack of elasticity in hardware meant that there were scalability risks associated with the systems in place, and these risks would surface whenever there was a sudden growth in the volume of data or when there was a market expansion for the business. Buying all this extra hardware up-front also meant that a huge capital expenditure investment had to be made for the hardware, with all the extra capacity lying unused from time to time. Also, software licenses had to be paid for and those were expensive, adding to the overall IT costs. Even after buying all the hardware upfront, it was difficult to maintain the data platform’s high performance all the time. As data volumes grew, latency started creeping in, which adversely affected the performance of certain critical systems. As data grow into big data, the type of data produced was not just structured data; a lot of business use cases required semi-structured data, such as JSON files, and even unstructured data, such as images and PDF files. In subsequent chapters, we will go through some use cases that specify different types of data. As the sources of data grew, so did the number of ETL pipelines. Managing these pipelines became cumbersome. And on top of that, with so much data movement, data started to duplicate at multiple places, which made it difficult to create a single source of truth for the data. On the flip side, with so many data sources and data owners within an organization, data became siloed, which made it difficult to share across different LOBs in the organization. This content is from the book “Modern Data Architecture on AWS” writtern by Behram Irani (Aug 2023). Start reading a free chapter or access the entire Packt digital library free for 7 days by signing up now. To learn more, click on the button below. Read through the Chapter 1 unlocked here...  🌟 Secret Knowledge: AI/LLM Resources🤖 How to Use Amazon CodeWhisperer for Command Line: Amazon introduces Amazon CodeWhisperer for the command line, enhancing developer productivity with contextual CLI completions and AI-driven natural language-to-bash translation. The tool provides CLI completions and translates natural language instructions into executable shell code snippets, modernizing the command line experience for over thirty million engineers. 🤖 How to Implement Emerging Practices for Society-Centered AI: The post underscores the importance of AI professionals addressing societal implications, advocating for multidisciplinary collaboration. It stresses the significance of measuring AI's impact on society to enhance effectiveness and identify areas for improvement in developing systems that benefit the broader community. 🤖 How to Speed Up and Improve LLM Output with Skeleton-of-Thought: The article introduces the Skeleton-of-Thought (SoT) approach, aiming to enhance the efficiency of Language Models (LLMs) by reducing generation latency and improving answer quality. SoT guides LLMs to generate answer skeletons first, then completes them in parallel, potentially accelerating open-source and API-based models for various question categories. 🤖 Understanding SuperNIC to Enhance AI Efficiency: The BlueField-3 SuperNIC is pivotal in AI-driven innovation, boosting workload efficiency and networking speed in AI cloud computing. With a 1:1 GPU to SuperNIC ratio, it enhances productivity. Integrated with NVIDIA Spectrum-4, it provides adaptive routing, out-of-order packet handling, and optimized congestion control for superior outcomes in enterprise data centers. 🤖 Step-by-step guide to the Evolution of LLMs: The post explores the 12-month evolution of Large Language Models (LLMs), from text completion to dynamic chatbots with code execution and knowledge access. It emphasizes the frequent release of new features, models, and techniques, notably the November 2022 launch of ChatGPT, accelerating user adoption and triggering an AI arms race, while questioning if such rapid advancements are bringing us closer to practical AI agents.  🔛 Masterclass: AI/LLM Tutorials👉 How to Get Started with Llama 2 in 5 Steps: Llama 2, an open-source large language model, is now free for research and commercial use. This blog outlines a five-step guide, covering prerequisites, model setup, fine-tuning, inference, and additional resources for users interested in utilizing Llama 2. 👉 How to Integrate GPT-4 with Python and Java: A Developer's Guide: The article explores integrating GPT-4 with Python and Java, emphasizing Python's compatibility and flexibility. It provides examples, discusses challenges like rate limits, and encourages collaboration for harnessing GPT-4's transformative potential, highlighting the importance of patience and debugging skills. 👉 How to Build an AI Assistant with Real-Time Web Access in 100 Lines of Code Using Python and GPT-4: This article guides readers in creating a Python-based AI assistant with real-time web access using GPT-4 in just 100 lines of code. The process involves initializing clients with API keys, creating the assistant using the OpenAI and Tavily libraries, and implementing a function for retrieving real-time information from the web. The author offers a detailed step-by-step guide with code snippets. 👉 Step-by-step guide to building a real-time recommendation engine with Amazon MSK and Rockset: This tutorial demonstrates building a real-time product recommendation engine using Amazon Managed Streaming for Apache Kafka (Amazon MSK) and Rockset. The architecture allows instant, personalized recommendations critical for e-commerce, utilizing Amazon MSK for capturing high-velocity user data and AWS Managed services for scalability in handling customer requests, API invocations, and data ingestion.  🚀 HackHub: Trending AI Tools💮 protectai/ai-exploits: Collection of real-world AI/ML exploits for responsibly disclosed vulnerabilities, aiming to raise awareness of the amount of vulnerable components in the AI/ML ecosystem. 💮 nlmatics/llmsherpa: Provides strategic APIs to accelerate LLM use cases, includes a LayoutPDFReader that provides layout information for PDF to text parsers, and is tested on a wide variety of PDFs. 💮 QwenLM/Qwen-Audio: Large audio language model proposed by Alibaba Cloud developers can use for speech editing, sound understanding and reasoning, music appreciation, and multi-turn dialogues in diverse audio-oriented scenarios. 💮 langchain-ai/opengpts: Open-source effort creating a similar experience to OpenAI's GPTs and Assistants API. It builds upon LangChain, LangServe, and LangSmith.  Readers’ Feedback! 💬 💭 Anish says, "The growing number of subscribers is really exciting. I particularly appreciate the transformation of 2D images into 3D models from Adobe and going through 'Tackling Hallucinations in LLMs' by Bijit Ghosh. These kinds of practical contexts are truly my preference for the upcoming newsletters." 💭 Tony says, "Very informative, far-reaching, and extremely timely. On point. Just keep it up, keep your eye on news and knowledge, and keep cluing us all once a week please, Merlyn. You're doing a fine job."  Share your thoughts here! Your opinions matter—let's make this space a reflection of diverse perspectives. 
Read more
  • 0
  • 0
  • 5859

article-image-joomla-flash-flashy-templates-headers-banners-and-tickers-part-2
Packt
18 Nov 2009
4 min read
Save for later

Joomla! with Flash: Flashy Templates, Headers, Banners, and Tickers: Part 2

Packt
18 Nov 2009
4 min read
Using Flash headers We have seen that one of the uses of Flash in Joomla! templates is as a header. By using a Flash animation in a site's header you can create some stunning effects. As we have already seen, while designing the template, we may embed Flash animation in the header region and control the layout using an appropriate CSS stylesheet. To embed such Flash animations like these, you can use the <object> </object> XHTML tag. We have seen its use in the previous section. An alternative to this is showing the Flash header at some module position. There are several extensions that can be used for showing Flash objects at a module position. We will be looking at some of them next. Using Flexheader3 Flexheader3 is a Joomla! 1.5-compatible extension for using Flash as headers in Joomla! sites. This is available for download for free at http://flexheader2.andrehotzler.de/en/download/folder/208-flexheader3.html. After downloading the package, install it from the Extensions | Install/Uninstall screen in Joomla! administration. Then click on Extensions | Module Manager. In the Module Manager screen, you will find the module named Flexheader3. Click on it and that shows the Module: [Edit] screen for the Flexheader3 module, as shown in the following screenshot: The Details section is similar to other modules from where you enable the module, select the module position to display this, select the order of display, and assign menus for which this module will be displayed. The module-specific settings are in the Parameters section. As you see, selecting the module position is crucial for this module. Most of the templates don't have a position to display the header using a module. Therefore, you may need to create a module position for displaying a Flash header. The following section shows you how to create a module position displaying a header. Creating a module position To create a module position in your template you need to edit at least two files. Browse to the /templates directory, and click on the name of the template that you want to modify. You need to edit two files in the template folder: index.php and templateDetails.xml. First, open the templateDetails.xml file in your text editor and find the <positions> tag. Under this, type the line highlighted in the following code so that the file looks like the following: <positions> <position>flexheader</position> <position>left</position> <position>user1</position> ... <position>right</position> <position>debug</position> </positions> Remember to type <position>flexheader</position> before ending </positions> tag. Placing it outside the <positions> </positions> block will make the template unusable. After modifying the templateDetails.xml file, open the index.php file in your text editor. Find out the code for including a header image in that template. Generally, this is done by inserting an image using the <img src=... /> tag. If you don't find such a tag, then look for <div id="header" ... > or something like that. In such cases, CSS is used to display the background image to the div element. Once you have found the code for showing the header image, replace it with the following code: <jdoc:include type="modules" name="flexheader" style="RAW" /> This line of code means that you are instructing to include modules designated for the flexheader position. When we assign the Flexheader3 module to this position, the contents of that module will be displayed in this position. Generally, this module will produce a code like the following in this position: <img src="/images/header.png" title="My header image" alt="Header image" style="width: 528px; height: 70px;" /> When changes to index.php are made, save those changes. We will be configuring the module to display a Flash header in this module position.
Read more
  • 0
  • 0
  • 5859

article-image-creating-application-scratch
Packt
13 Nov 2013
5 min read
Save for later

Creating an Application from Scratch

Packt
13 Nov 2013
5 min read
(For more resources related to this topic, see here.) Creating an application Using the Command Line Tool, we are going to create a very new application. This application is also going to be a Sinatra application that displays some basic date and time information. First, navigate to a new directory that will be used to contain the code. Everything in this directory will be uploaded to AppFog when we create the new application. $ mkdir insideaf4 $ cd insideaf4 Now, create a new file called insideaf4.rb. The contents of the file should look like the following: require 'sinatra' get '/' do erb :index end This tells Sinatra to listen for requests to the base URL of / and then render the index page that we will create next. If you are using Ruby 1.8.7, you may need to add the following line at the top: require 'rubygems' Next, create a new directory called views under the insideaf4 directory: $ mkdir views $ cd views Now we are going to create a new file under the views directory called index.erb. This file will be the one that displays the date and time information for our example. The following are the contents of the index.erb file: <html><head> <title>Current Time</title> </head><body> <% time = Time.new %> <h1>Current Time</h1> <table border="1" cellpadding="5"> <tr> <td>Name</td> <td>Value</td> </tr> <tr> <td>Date (M/D/Y)</td> <td<%= time.strftime('%m/%d/%Y') % </tr> <tr> <td>Time</td> <td><%= time.strftime('%I:%M %p') </tr> <tr> <td>Month</td> <td><%= time.strftime('%B') %></t </tr> <tr> <td>Day</td> <td><%= time.strftime('%A') %></td </tr> </table> </body></html> This file will create a table that shows a number of different ways to format the date and time. Embeded in the HTML code are Ruby snippets that look like <%= %>. Inside of these snippets we use Ruby's strftime method to display the current date and time in a number of different string formats. At the beginning of the file, we create a new instance of a Time object which is automatically set to the current time. Then we use the strftime method to display different values in the table. For more information on using Ruby dates, please see the documentation available at http://www.ruby-doc.org/core-2.0.0/Time.html. Testing the application Before creating an application in AppFog, it is useful to test it out locally first. To do this you will again need the Sinatra Gem installed. If you need to do that, refer to Appendix, Installing the AppFog Gem. The following is the command to run your small application: $ ruby indiseaf4.rb You will see the Sinatra application start and then you can navigate to http://localhost:4567/ in a browser. You should see a page that has the current date and time information like the following screenshot: To terminate the application, return to the command line and press Control+C. Publishing to AppFog Now that you have a working application, you can publish it to AppFog and create the new AppFog application. Before you begin, make sure you are in the root director of your project. For this example that was the insideaf4 directory. Next, you will need to log in to AppFog. $ af login Attempting login to [https://api.appfog.com] Email: matt@somecompany.com Password: ******** Successfully logged into [https://api.appfog.com] You may be asked for your e-mail and password again, but the tool may remember your session if you logged in recently. Now you can push your application to AppFog, which will create a new application for you. Make sure you are in the correct directory and use the Push command. You will be prompted for a number of settings during the publishing process. In each case there will be a list of options along with a default. The default value will be listed with a capital letter or listed by itself in square brackets. For our purposes, you can just press Enter for each prompt to accept the default value. The only exception to that is the step that prompts you to choose an infrastructure. In that step you will need to make a selection. $ af push insideaf4 Would you like to deploy from the current directory? [Yn]: Detected a Sinatra Application, is this correct? [Yn]: 1: AWS US East - Virginia 2: AWS EU West - Ireland 3: AWS Asia SE - Singapore 4: HP AZ 2 - Las Vegas Select Infrastructure: Application Deployed URL [insideaf4.aws.af.cm]: Memory reservation (128M, 256M, 512M, 1G, 2G) [128M]: How many instances? [1]: Bind existing services to insideaf4? [yN]: Create services to bind to insideaf4? [yN]: Would you like to save this configuration? [yN]: Creating Application: OK Uploading Application: Checking for available resources: OK Packing application: OK Uploading (1K): OK Push Status: OK Staging Application insideaf4: OK Starting Application insideaf4: OK Summary Hence we have learned how to create application using Appfog. Resources for Article : Further resources on this subject: AppFog Top Features You Need to Know [Article] SSo, what is Node.js? [Article] Learning to add dependencies [Article]
Read more
  • 0
  • 0
  • 5858

article-image-ajax-chat-implementation-part-2
Packt
28 Dec 2009
9 min read
Save for later

AJAX Chat Implementation: Part 2

Packt
28 Dec 2009
9 min read
Create a new file named index.html, and add this code to it: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xml_lang="en" lang="en"> <head> <title>AJAX Chat</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="chat.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="jQuery-1.3.2.js" ></script> <script type="text/javascript" src="chat.js" ></script> </head> <body> <noscript> Your browser does not support JavaScript!! </noscript> <table id="content"> <tr> <td> <div id="scroll"> </div> </td> <td id="colorpicker"> <img src="palette.png" id="palette" alt="Color Palette" border="1"/> <br /> <input id="color" type="hidden" readonly="true" value="#000000" /> <span id="sampleText"> (text will look like this) </span> </td> </tr> </table> <div> <input type="text" id="userName" maxlength="10" size="10"/> <input type="text" id="messageBox" maxlength="2000" size="50" /> <input type="button" value="Send" id="send" /> <input type="button" value="Delete All" id="delete" /> </div> </body> </html> Let's deal with appearances now, creating chat.css and adding the following code to it: body { font-family: Tahoma, Helvetica, sans-serif; margin: 1px; font-size: 12px; text-align: left } #content { border: DarkGreen 1px solid; margin-bottom: 10px } input { border: #999 1px solid; font-size: 10px } #scroll { position: relative; width: 340px; height: 270px; overflow: auto } .item { margin-bottom: 6px } #colorpicker { text-align:center } It's time for another test. We still don't have the color picker in place, but other than that, we have the whole client-server chat mechanism in place. Load index.html at http://localhost/ajax/chat/index.html from multiple browsers and/or computers, and ensure everything works as planned. Figure 8-7: Screenshot of index.html Copy palette.png from the code download to your ajax/chat folder. Create a file named color.php and add the following code to it. This is actually the only step left to make the color picker work as expected. <?php // the name of the image file $imgfile='palette.png'; // load the image file $img=imagecreatefrompng($imgfile); // obtain the coordinates of the point clicked by the user $offsetx=$_GET['offsetx']; $offsety=$_GET['offsety']; // get the clicked color $rgb = ImageColorAt($img, $offsetx, $offsety); $r = ($rgb >> 16) & 0xFF; $g = ($rgb >> 8) & 0xFF; $b = $rgb & 0xFF; // return the color code echo json_encode(array("color" => sprintf('#%02s%02s%02s', dechex($r), dechex($g), dechex($b)))); ?> Make another test to ensure the color picker works and that your users can finally chat in color. What just happened? First, make sure the application works well. Load http://localhost/ajax/chat/index.html with a web browser, and you should get a page that looks like the one in Figure 8-1. If you analyze the code for a bit, the details will become clear. Everything starts with index.html. The only part that is really interesting in index.html is a scrolling region implemented in DHTML. (A little piece of information regarding scrolling can be found at http://www.dyn-web.com/code/scroll/.) The scrolling area allows our users to scroll up and down the history of the chat and ensures that any new messages that might flow out of the area are still viewed. In our example, the scroll element and its inner layers do the trick. The scroll element is the outermost layer; it has a fixed width and height; and its most useful property, overflow, determines how any content that falls (or overflows) outside of its boundaries is displayed. Generally, the content of a block box is confined to the content edges of the box. In CSS, the overflow property has four possible values that specify what should happen when an element overflows its area: visible, hidden, scroll, and auto. (For more details, please see the specification of overflow, at http://www.w3.org/TR/REC-CSS2/visufx.html.)   As you can see, the HTML file is very clean. It contains only the declarations of the HTML elements that make up the user interface. There are no event handlers and there is no JavaScript code inside the HTML file—we have a clean separation between the user interface and the programming. In our client-side JavaScript code, in the chat.js file, the action starts with the ready event, which is defined in jQuery (reference: http://docs.jQuery.com/Events/ready) as a replacement for window.onload. In other words, your ready() function, which you can see in the following code snippet, is called automatically after the HTML page has been loaded by the browser, and the page elements can be safely used and manipulated by your JavaScript code: $(document).ready(function() { } Inside this function, we do several operations involving events related to the user interface. Let's analyze each step! We want to be sure that a username always appears, that is, it should never be left empty. To do this, we can create a function that checks for this and bind it to the blur event of the textbox. // function that ensures that the username is never empty and //if so a random name is generated $('#userName').blur( function(e) { // ensures our user has a default random name when the form loads if (this.value == "") this.value = "Guest" + Math.floor(Math.random() * 1000); } ); If the username is empty, we simply generate a random username suffixing Guest with a randomly generated number. When the page first loads, no username has been set and we trigger the blur event on userName. // populate the username field with // the default value $('#userName').triggerHandler('blur'); The success() function starts by checking if the JSON response contains an errno field, which would mean that an error has happened on the server side. If an error occurred the displayPHPError() function is called passing in the error in JSON format. // function that displays a PHP error message function displayPHPError(error) { displayError ("Error number :" + error.errno + "rn" + "Text :"+ error.text + "rn" + "Location :" + error.location + "rn" + "Line :" + error.line + + "rn"); } The displayPHPError() will retrieve the information from the error and call in turn the displayError() function. The displayError() function shows the error message or a generic alert depending on whether the debugging flag is set or not. // function that displays an error message function displayError(message) { // display error message, with more technical details if debugMode is true alert("Error accessing the server! " + (debugMode ? message : "")); } Next, in our ready event, we set the default color for the sample text to black: // set the default color to black $('#sampleText').css('color', 'black'); Moving on, we hook on to the click event of the Send button. The following code is very simple, as the entire logic behind sending a message is encapsulated in sendMessage(): $('#send').click( function(e) { sendMessage(); } ); Moreover, here we hook on to the click event of the Delete all button in a similar way as the Send button. $('#delete').click( function(e) { deleteMessages(); } ); For the messageBox textbox, where we input messages, we disable autocomplete and we capture the Enter key and invoke the logic for sending a message: // set autocomplete off $('#messageBox').attr('autocomplete', 'off'); // handle the enter key event $('#messageBox').keydown( function(e) { if (e.keyCode == 13) { sendMessage(); } } ); Finally, when the page loads, we want to have the messages that have already been posted and we call retrieveNewMessages() function. Now that we have seen what happens when the page loads, it's time to analyze the logic behind sending and receiving new messages. Because everything starts when the page loads and the existing messages are retrieved, we will start with retrieveNewMessages() function. The function simply makes an AJAX request to the server indicating the retrieval of the latest messages. function retrieveNewMessages() { $.ajax({ url: chatURL, type: 'POST', data: $.param({ mode: 'RetrieveNew', id: lastMessageID }), dataType: 'json', error: function(xhr, textStatus, errorThrown) { displayError(textStatus); }, success: function(data, textStatus) { if(data.errno != null) displayPHPError(data); else readMessages(data); // restart sequence setTimeout("retrieveNewMessages();", updateInterval); } }); } The request contains as parameters the mode indicating the retrieval of new messages and the ID of the last retrieved message: data: $.param({ mode: 'RetrieveNew', id: lastMessageID }), On success, we simply read the retrieved messages and we schedule a new automatic retrieval after a specific period of time: success: function(data, textStatus) { if(data.errno != null) displayPHPError(data); else readMessages(data); // restart sequence setTimeout("retrieveNewMessages();", updateInterval); } Reading messages is the most complicated function as it involves several steps. It starts by checking whether the database has been cleared of messages and, if so, it empties the list of messages and resets the ID of the last retrieved message. function readMessages(data, textStatus) { // retrieve the flag that says if the chat window has been cleared or not clearChat = data.clear; // if the flag is set to true, we need to clear the chat window if (clearChat == 'true') { // clear chat window and reset the id $('#scroll')[0].innerHTML = ""; lastMessageID = -1; } Before retrieving the new messages, we need to check and see if the received messages have not been already processed. If not, we simply store the ID of the last received message in order to know what messages to ask for during the next requests: if (data.messages.length > 0) { // check to see if the first message // has been already received and if so // ignore the rest of the messages if(lastMessageID > data.messages[0].id) return; // the ID of the last received message is stored locally lastMessageID = data.messages[data.messages.length - 1].id; }
Read more
  • 0
  • 0
  • 5857

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
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 $19.99/month. Cancel anytime
article-image-marionette-view-types-and-their-use
Packt
07 Jan 2014
15 min read
Save for later

Marionette View Types and Their Use

Packt
07 Jan 2014
15 min read
(For more resources related to this topic, see here.) Marionette.View and Marionette.ItemView The Marionete.View extends the Backbone.View, and it's important to remember this, because all the knowledge that we already have on creating a view will be useful while working with these new set of views of Marionette. Each of them aims to provide a specific out of the box functionality so that you spend less time focusing on the glue code needed to make things work, and more time on things that are related to the needs of your application. This allows you to focus all your attention on the specific logic of your application. We will start by describing the Marionette.View part of Marionette, as all of the other views extend from it; the reason we do this is because this view provides a very useful functionality. But it's important to notice that this view is not intended to be used directly. As it is the base view from which all the other views inherit from, it is an excellent place to contain some of the glue code that we just talked about. A good example of that functionality is the close method, which will be responsible for removing .el from DOM. This method will also take care of calling unbind to all your events, thus avoiding the problem called Zombie views. This an issue that you can have if you don't do this carefully in a regular Backbone view, where new instantiations of previously closed fire events are present. These events remain bound to the HTML elements used in the view. These are now present again in the DOM now that the view has been rerendered, and during the recreation of the view, new event listeners are attached to these HTML elements. From the documentation of the Marionette.View, we exactly know what the close method does. It calls an onBeforeClose event on the view, if one is provided It calls an onClose event on the view, if one is provided It unbinds all custom view events It unbinds all DOM events It removes this.el from the DOM It unbinds all listenTo events The link to the official documentation of the Marionette.View object is https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.view.md. It's important to mention that the third point, unbind all custom view events, will unbind events created using the modelEvents hash, those created on the events hash, and events created via this.listenTo. As the close method is already provided and implemented, you don't need to perform the unbind and remove previously listed tasks. While most of the time this would be enough, at times, one of your views will need you to perform extra work in order to properly close it; in this case, two events will be fired at the same time to close a view. The event onBeforeClose, as the name indicates, will be fired just before the close method. It will call a function of the same name, onBeforeClose, where we can add the code that needs to be executed at this point. function : onBeforeClose () { // code to be run before closing the view } The second event will be onClose, which will be fired after the close method so that the .el of the view won't be present anymore and all the unbind tasks will have been performed. function : onClose () { // code to be run after closing the view } One of the core ideas behind Marionette is to reduce the boilerplate code that you have to write when building apps with Backbone. A perfect example of which is the render method that you have to implement in every Backbone view, and the code there is pretty much the same in each of your views. Load the template with the underscore _.template function and then pass the model converted to JSON to the template. The following is an example of repetitive code needed to render a view in Backbone: render : function () { var template = $( '#mytemplate' ).html(); var templateFunction = _.template( template ); var modelToJSON = this.model.toJSON(); var result = templateFunction(modelToJSON); var myElement = $( '#MyElement' ); myElement.html( result ); } As Marionette defining a render function is no longer required, just like the close method, the preceding code will be called for you behind the scenes. In order to render a view, we just need to declare it with a template property set. var SampleView = Backbone.Marionette.ItemView.extend({ template : '#sample-template' }); Next, we just create a Backbone model, and we pass it to the ItemView constructor. var SampleModel = Backbone.Model.extend({ defaults : { value1 : "A random Value", value2 : "Another Random Value" } }) var sampleModel = new SampleModel(); var sampleView = new SampleView({model:sampleModel); And then the only thing left is to call the render function. sampleView.render(); If you want to see it running, please go through this JSFiddle that illustrates the previous code: http://jsfiddle.net/rayweb_on/VS9hA/ One thing to note is that we just needed one line to specify the template, and Marionette did the rest by rendering our view with the specified template. Notice that in this example, we used the ItemView constructor; we should not use Marionette.View directly, as it does not have many functionalities of its own. It just serves as the base for other views. So some of the following examples of the functionalities provided by Marionette.View will be demonstrated using ItemView, as this view inherits all of these functionalities through extension. As we saw in the previous example, ItemView works perfectly for rendering a single model using a template, but what about rendering a collection of models? If you just need to render, for example, a list of books or categories, you still can use ItemView. To accomplish this, the template that you would assign to ItemView must know how to handle the creation of the DOM to properly display that list of items. Let's render a list of books. The Backbone model will have two properties: the book name and the book ID. We just want to create a list of links using the book name as the value to be displayed; the ID of the book will be used to create a link to see the specific book. First, let's create the book Backbone model for this example and its collection: var BookModel = Backbone.Model.extend({ defaults : { id : "1", name : "First", } }); var BookCollection = Backbone.Collection.extend({ model : BookModel }); Now let's instantiate the collection and add three models to it: var bookModel = new BookModel(); var bookModel2 = new BookModel({id:"2",name:"second"}); var bookModel3 = new BookModel({id:"3",name:"third"}); var bookCollection = new BookCollection(); bookCollection.add(bookModel); bookCollection.add(bookModel2); bookCollection.add(bookModel3); In our HTML, let's create the template to be used in this view; the template should look like the following: <script id="books-template" type="text/html"> <ul> <% _.each(items, function(item){ %> <li><a href="book/'+<%= item.id %> +"><%= item.name %> </li> <% }); %> </ul> </script> Now we could render the book list using the following code snippet: var BookListView = Marionette.ItemView.extend({ template: "#books-template" }); var view = new BookListView ({ collection: bookCollection }); view.Render(); If you want to see it in action, go to the working code in JSFiddle at http://jsfiddle.net/rayweb_on/8QAgQ/. The previous code would produce an unordered list of books with links to the specific book. Again, we gained the benefit of writing very little code once again, as we didn't need to specify the Render function, which could be misleading, because the ItemView is perfectly capable of rendering a model or a collection. Whether to use CollectionView or ItemView will depend on what we are trying to accomplish. If we need a set of individual views with its own functionality, CollectionView is the right choice, as we will see when we get to the point of reviewing it. But if we just need to render the values of a collection, ItemView would be the perfect choice. Handling events in the views To keep track of model events or collection events, we must write the following code snippet on a regular Backbone view: this.listenTo(this.model, "change:title", this.titleChanged); this.listenTo(this.collection, "add", this.collectionChanged); To start these events, we use the following handler functions: titleChanged: function(model, value){alert("changed");}, collectionChanged: function(model, value){alert("added");}, This still works fine in Marionette, but we can accomplish the same thing by declaring these events using the following configuration hash: modelEvents: { "change:title": "titleChanged" }, collectionEvents: { "add": "collectionChanged" }, This will give us exactly the same result, but the configuration hash is very convenient as we can keep adding events to our model or collection, and the code is cleaner and very easy to follow. The modelEvents and collectionEvents are not the only configuration hash sets that we have available in each one of the Marionette views; the UI configuration hash is also available. It may be the case that one of the DOM elements on your view will be used many times to read its value, and doing this using jQuery can not be optimal in terms of performance. Also, we would have the jQuery reference in several places, repeating ourselves and making our code less DRY. Inside a Backbone view, we can define a set of events that will be fired once an action is taken in the DOM; for instance, we pass the function that we want to handle in this event at the click of a button. events : { "click #button2" : "updateValue" }, This will invoke the updateValue function once we click on button2. This works fine, but what about calling a method that is not inside the view? To accomplish this, Marionette provides the triggers functionality that will fire events which can be listened to outside of your view. To declare a trigger, we can use the same syntax used in the events object as follows: triggers : { "click #button1": "trigger:alert"}, And then, we can listen to that event somewhere else using the following code: sampleView.on("trigger:alert", function(args){ alert(args.model.get("value2")); }); In the previous code, we used the model to alert and display the value of the property, value2. The args parameter received by the function will contain objects that you can use: The view that fired the trigger The Backbone model or collection of that view UI and templates While working with a view, you will need a reference to a particular HTML element through jQuery in more than one place in your view. This means you will make a reference to a button during initialization and in few other methods of the view. To avoid having the jQuery selector duplicated on each of these methods, you can map that UI element in a hash so that the selector is preserved. If you need to change it, the change will be done in a single place. To create this mapping of UI elements, we need to add the following declaration: ui: { quantity: "#quantity" saveButton : "#Save" }, And to make use of these mapper UI elements, we just need to refer them inside any function by the name given in the configuration. validateQuantity: function() { if (this.ui.quantity.val() > 0 { this.ui.saveButton.addClass('active'); } } There will be times when you need to pass a different template to your view. To do this in Marionette, we remove the template declaration and instead add a function called getTemplate. The following code snippet would illustrate the use of this function: getTemplate: function(){ if (this.model.get("foo"){ return "#sample-template"; }else { return "#a-different-template"; } }, In this case, we check the existence of the property foo; if it's not present, we use a different template and that will be it. You don't need to specify the render function because it will work the same way as declaring a template variable as seen in one of the previous examples. If you want to learn more about all the concepts that we have discussed so far, please refer to the jsFiddle link: http://jsfiddle.net/rayweb_on/NaHQS/. If you find yourself needing to make calculations involving a complicated process while rendering a value, you can make use of templeteHelpers that are functions contained in an object called templateHelpers. Let's look at an example that will illustrate its use better. Suppose we need to show the value of a book but are offering a discount that we need to calculate, use the following code: var PriceView = Backbone.Marionette.ItemView.extend({ template: "#price-template", templateHelpers: { calculatePrice: function(){ // logic to calculate the price goes here return price; } } }); As you can see the in the previous code, we declared an object literal that will contain functions that can be called from the templates. <script id="my-template" type="text/html"> Take this book with you for just : <%= calculatePrice () %> </script> Marionette.CollectionView Rendering a list of things like books inside one view is possible, but we want to be able to interact with each item. The solution for this will be to create a view one-by-one with the help of a loop. But Marionette solves this in a very elegant way by introducing the concept of CollectionView that will render a child view for each of the elements that we have in the collection we want to display. A good example to put into practice could be to list the books by category and create a Collection view. This is incredible easy. First, you need to define how each of your items should be displayed; this means how each item will be transformed in a view. For our categories example, we want each item to be a list <li> element and part of our collection; the <ul> list will contain each category view. We first declare ItemView as follows: var CategoryView = Backbone.Marionette.ItemView.extend({ tagName : 'li', template: "#categoryTemplate", }); Then we declare CollectionView, which specifies the view item to use. var CategoriesView = Backbone.Marionette.CollectionView.extend({ tagName : 'ul', className : 'unstyled', itemView: CategoryView }); A good thing to notice is that even when we are using Marionette views, we are still able to use the standard properties that Backbone views offer, such as tagName and ClassName. Finally, we create a collection and we instantiate CollectionView by passing the collection as a parameter. var categoriesView = new CategoriesView({collection:categories); categoriesView.render(); And that's it. Simple huh? The advantage of using this view is that it will render a view for each item, and it can have a lot of functionality; we can control all those views in the CollectionView that serves as a container. You can see it in action at http://jsfiddle.net/rayweb_on/7usdJ/. Marionette.CompositeView The Marionette.Composite view offers the possibility of not only rendering a model or collection models but, also the possibility of rendering both a model and a collection. That's why this view fits perfectly in our BookStore website. We will be adding single items to the shopping cart, books in this case, and we will be storing these books in a collection. But we need to calculate the subtotal of the order, show the calculated tax, and an order total; all of these properties will be part of our totals model that we will be displaying along with the ordered books. But there is a problem. What should we display in the order region when there are no items added? Well, in the CompositeView and the CollectionView, we can set an emptyView property, which will be a view to show in case there are no models in the collection. Once we add a model, we can then render the item and the totals model. Perhaps at this point, you may think that you lost control over your render functionality, and there will be cases where you need to do things to modify your HTML. Well, in that scenario, you should use the onRender() function, which is a very helpful method that will allow you to manipulate the DOM just after your render method was called. Finally, we would like to set a template with some headers. These headers are not part of an ItemView, so how can we display it? Let's have a look at part of the code snippet that explains how each part solves our needs. var OrderListView = Backbone.Marionette.CompositeView.extend({ tagName: "table", template: "#orderGrid", itemView: CartApp.OrderItemView, emptyView: CartApp.EmptyOrderView, className: "table table-hover table-condensed", appendHtml: function (collectionView, itemView) { collectionView.$("tbody").append(itemView.el); }, So far we defined the view and set the template; the Itemview and EmptyView properties will be used to render our view. The onBeforeRender is a function that will be called, as the name indicates, before the render method; this function will allow us to calculate the totals that will be displayed in the total model. onBeforeRender: function () { var subtotal = this.collection.getTotal(); var tax = subtotal * .08; var total = subtotal + tax; this.model.set({ subtotal: subtotal }); this.model.set({ tax: tax }); this.model.set({ total: total }); }, The onRender method is used here to check whether there are no models in the collection (that is, the user hasn't added a book to the shopping cart). If not, we should not display the header and footer regions of the view. onRender: function () { if (this.collection.length > 0) { this.$('thead').removeClass('hide'); this.$('tfoot').removeClass('hide'); } }, As we can see, Marionette does a great job offering functions that can remove a lot of boilerplate code and also give us full control over what is being rendered. Summary This article covered the introduction and usage of view types that Marionette has. Now you must be quite familiar with the Marionette.View and Marionette.ItemView view types of Marionette. Resources for Article: Further resources on this subject: Mobile Devices [Article] Puppet: Integrating External Tools [Article] Understanding Backbone [Article]
Read more
  • 0
  • 0
  • 5850

article-image-fine-tuning-sql-server-database-dynamics-nav
Packt
24 Sep 2010
5 min read
Save for later

Fine-tuning the SQL Server database for Dynamics NAV

Packt
24 Sep 2010
5 min read
  Microsoft Dynamics NAV Administration A quick guide to install, configure, deploy, and administer Dynamics NAV with ease Install, configure, deploy and administer Dynamics NAV with ease Install Dynamics NAV Classic Client (Dynamics NAV C/SIDE), Dynamics NAV Role Tailored Client (RTC), and Dynamics NAV Classic Database Server on your computer to manage enterprise data Connect Dynamics NAV clients to the Database Server in the earlier versions and also the latest Dynamics NAV 2009 version A step-by-step guide filled with examples to help you to accomplish administrative tasks such as securing and maintaining databases using Dynamics NAV   Read more about this book (For more resources on Microsoft see here.) SIFT In the Classic database server option, SIFT (Sum Index Flow Technology) is used to make the calculation of balances, sums, and so on. In any other database, this is normally done through calculations and could be a time-consuming process if there are thousands of records in the table. The SIFT data is stored in indexes, which are also called secondary keys in the Classic database server option. The balances based on the "secondary keys" are stored in separate indexes in the database. The programmer can define which fields need calculation by defining the SumIndexFields for the keys, as represented in the following screenshot. Therefore, the retrieval time for things such as account balances and such others is minimal, making the application extremely fast: What gives a boost to SIFT is the ability to filter on the underlying values that make up SIFT balances. This technology is also known as the flow filter technology, which complements the basic SIFT technology in a significant way. When SIFT was initially implemented on the Microsoft SQL Server database option for Dynamics NAV, it was done by storing these SIFT columns in summarized tables called SIFT tables that were continuously updated through SQL triggers. Thus, the procedure was expensive and took a toll on the performance when a table containing SIFT indexes was updated. From the Dynamics NAV 5.0 Service Pack 1 version, Microsoft decided to use indexed views in SQL Server instead of SIFT tables. Dynamics NAV creates one SQL indexed view per key, regardless of how many sum indexed fields there are in that key. Having too many SIFT indexes can adversely affect the performance of the application. Having too many fields in the SIFT indexes is also not advisable. The MaintainSIFTIndex property of the index in the base table could be used to optimally design the SIFT indexes. If there is the possibility of the base table not growing so rapidly, it is recommended to keep the MaintainSIFTIndex property to No. For more information about SQL indexed views, we can refer to the Microsoft SQL library. Using indexes/keys in Dynamics NAV Maintaining indexes for Microsoft Dynamics NAV has also been seen as a big performance issue. This is one of the major reasons for performance issues in the Dynamics NAV Classic database. The Microsoft SQL Server is clever enough to sort the data without any index, if the dataset being sorted is not huge. To access these properties of the keys, go to Object Designer, highlight the table in which the key needs to be modified, click on Design to open the list of fields in the table, and go to View | Keys. A window similar to the following screenshot opens, showing the list of keys: To open the properties of a particular key, highlight the key and then click on View| Properties, as shown in the following screenshot: These indexes or keys could be used optimally by using the following properties of the keys: Enabled: This is a property to enable or disable an individual key. A lot of times, developers create a one-off key to be used in a particular report or another piece of customization. This one-off key can be disabled or enabled based on the utilization or frequency of the use of customization. SumIndexFields: This property is used to define the SumIndexFields (whose sum needs to be maintained in the SQL indexed views). A maximum of 20 SumIndexedFields can be selected. KeyGroups: This is a method of combining the various keys together so that they could be enabled or disabled together. For example, in the following screenshot we see that the, Key Group property is defined as Consol, which is one of the key groups in the database. Keys can be combined together based on the nature of the use of keys or a particular application area. To enable or disable a key group, go to File | Database | Information. Click on the Key Group button in the bottom of the Database Information form to open a list of key groups defined in the database. MaintainSQLIndex: Microsoft SQL Server is clever enough to sort the data without an index, though to have the SQL Server sort faster, an index of the fields to be sorted can be created. Any writes to the table will be slower, as the number of indexes in a table grows, as those indexes will have to be updated along with each write transaction. MaintainSIFTIndex:We need to set this property to No if the data to be maintained in the SIFT base tables is less. Clustered: This is where we define whether or not the index is clustered. Clustered indexes are used to specify the sorting of data as it pertains to the storage in the table. In Dynamics NAV and also in a SQL Server database, a primary key is a clustered index by default. SQLIndex: We can specify here the actual list of fields that need to be a part of the SQL index. Investigating the performance of the database There are a few key performance troubleshooting techniques that are effective in identifying the bottlenecks in the performance of the database.
Read more
  • 0
  • 0
  • 5850

article-image-network-exploitation-and-monitoring
Packt
22 May 2014
8 min read
Save for later

Network Exploitation and Monitoring

Packt
22 May 2014
8 min read
(For more resources related to this topic, see here.) Man-in-the-middle attacks Using ARP abuse, we can actually perform more elaborate man-in-the-middle (MITM)-style attacks building on the ability to abuse address resolution and host identification schemes. This section will focus on the methods you can use to do just that. MITM attacks are aimed at fooling two entities on a given network into communicating by the proxy of an unauthorized third party, or allowing a third party to access information in transit, being communicated between two entities on a network. For instance, when a victim connects to a service on the local network or on a remote network, a man-in-the-middle attack will give you as an attacker the ability to eavesdrop on or even augment the communication happening between the victim and its service. By service, we could mean a web (HTTP), FTP, RDP service, or really anything that doesn't have the inherent means to defend itself against MITM attacks, which turns out to be quite a lot of the services we use today! Ettercap DNS spoofing Ettercap is a tool that facilitates a simple command line and graphical interface to perform MITM attacks using a variety of techniques. In this section, we will be focusing on applications of ARP spoofing attacks, namely DNS spoofing. You can set up a DNS spoofing attack with ettercap by performing the following steps: Before we get ettercap up and running, we need to modify the file that holds the DNS records for our soon-to-be-spoofed DNS server. This file is found under /usr/share/ettercap/etter.dns. What you need to do is either add DNS name and IP addresses or modify the ones currently in the file by replacing all the IPs with yours, if you'd like to act as the intercepting host. Now that our DNS server records are set up, we can invoke ettercap. Invoking ettercap is pretty straightforward; here's the usage specification: ettercap [OPTIONS] [TARGET1] [TARGET2] To perform a MITM attack using ettercap, you need to supply the –M switch and pass it an argument indicating the MITM method you'd like to use. In addition, you will also need to specify that you'd like to use the DNS spoofing plugin. Here's what the invocation will look like: ettercap –M arp:remote –P dns_spoof [TARGET1] [TARGET2] Where TARGET1 and TARGET2 is the host you want to intercept and either the default gateway or DNS server, interchangeably. To target the host at address 192.168.10.106 with a default gateway of 192.168.10.1, you will invoke the following command: ettercap –M arp:remote –P dns_spoof /192.168.10.107//192.168.10.1/ Once launched, ettercap will begin poisoning the ARP tables of the specified hosts and listen for any DNS requests to the domains it's configured to resolve. Interrogating servers For any network device to participate in communication, certain information needs to be accessible to it, no device will be able to look up a domain name or find an IP address without the participation of devices in charge of certain information. In this section, we will detail some techniques you can use to interrogate common network components for sensitive information about your target network and the hosts on it. SNMP interrogation The Simple Network Management Protocol (SNMP) is used by routers and other network components in order to support remote monitoring of things such as bandwidth, CPU/Memory usage, hard disk space usage, logged on users, running processes, and a number of other incredibly sensitive collections of information. Naturally, any penetration tester with an exposed SNMP service on their target network will need to know how to proliferate any potentially useful information from it. About SNMP Security SNMP services before Version 3 are not designed with security in mind. Authentication to these services often comes in the form a simple string of characters called a community string. Another common implementation flaw that is inherent to SNMP Version 1 and 2 is the ability to brute-force and eavesdrop on communication. To enumerate SNMP servers for information using the Kali Linux tools, you could resort to a number of techniques. The most obvious one will be snmpwalk, and you can use it by using the following command: snmpwalk –v [1 | 2c | 3 ] –c [community string] [target host] For example, let's say we were targeting 192.168.10.103 with a community string of public, which is a common community string setting; you will then invoke the following command to get information from the SNMP service: snmpwalk –v 1 –c public 192.168.10.103 Here, we opted to use SNMP Version 1, hence the –v 1 in the invocation for the preceding command. The output will look something like the following screenshot: As you can see, this actually extracts some pretty detailed information about the targeted host. Whether this is a critical vulnerability or not will depend on which kind of information is exposed. On Microsoft Windows machines and some popular router operating systems, SNMP services could expose user credentials and even allow remote attackers to augment them maliciously, should they have write access to the SNMP database. Exploiting SNMP successfully is often strongly depended on the device implementing the service. You could imagine that for routers, your target will probably be the routing table or the user accounts on the device. For other host types, the attack surface may be quite different. Try to assess the risk of SNMP-based flaws and information leaks with respect to its host and possibly the wider network it's hosted on. Don't forget that SNMP is all about sharing information, information that other hosts on your network probably trust. Think about the kind of information accessible and what you will be able to do with it should you have the ability to influence it. If you can attack the host, attack the hosts that trust it. Another collection of tools is really great at collecting information from SNMP services: the snmp_enum, snmp_login, and similar scripts available in the Metasploit Framework. The snmp_enum script pretty much does exactly what snmpwalk does except it structures the extracted information in a friendlier format. This makes it easier to understand. Here's an example: msfcli auxiliary/scanner/snmp/snmp_enum [OPTIONS] [MODE] The options available for this module are shown in the following screenshot: Here's an example invocation against the host in our running example: msfcli auxiliary/scanner/snmp/snmp_enum RHOSTS=192.168.10.103 The preceding command produces the following output: You will notice that we didn't specify the community string in the invocation. This is because the module assumes a default of public. You can specify a different one using the COMMUNITY parameter. In other situations, you may not always be lucky enough to preemptively know the community string being used. However, luckily SNMP Version 1, 2, 2c, and 3c do not inherently have any protection against brute-force attacks, nor do any of them use any form of network based encryption. In the case of SNMP Version 1 and 2c, you could use a nifty Metasploit module called snmp-login that will run through a list of possible community strings and determine the level of access the enumerated strings gives you. You can use it by running the following command: msfcli auxiliary/scanner/snmp/snmp_login RHOSTS=192.168.10.103 The preceding command produces the following output: As seen in the preceding screenshot, once the run is complete it will list the enumerated strings along with the level of access granted. The snmp_login module uses a static list of possible strings to do its enumeration by default, but you could also run this module on some of the password lists that ship with Kali Linux, as follows: msfcli auxiliary/scanner/snmp/snmp_login PASS_FILE=/usr/share/wordlists/ rockyou.txt RHOSTS=192.168.10.103 This will use the rockyou.txt wordlist to look for strings to guess with. Because all of these Metasploit modules are command line-driven, you can of course combine them. For instance, if you'd like to brute-force a host for the SNMP community strings and then run the enumeration module on the strings it finds, you can do this by crafting a bash script as shown in the following example: #!/bin/bash if [ $# != 1 ] then echo "USAGE: . snmp [HOST]" exit 1 fi TARGET=$1 echo "[*] Running SNMP enumeration on '$TARGET'" for comm_string in `msfcli auxiliary/scanner/snmp/snmp_login RHOSTS=$TARGET E 2> /dev/null | awk -F' '/access with community/ { print $2 }'`; do echo "[*] found community string '$comm_string' ...running enumeration"; msfcli auxiliary/scanner/snmp/snmp_enum RHOSTS=$TARGET COMMUNITY=$comm_string E 2> /dev/null; done The following command shows you how to use it: . snmp.sh [TAGRET] In our running example, it is used as follows: . snmp.sh 192.168.10.103 Other than guessing or brute-forcing SNMP community strings, you could also use TCPDump to filter out any packets that could contain unencrypted SNMP authentication information. Here's a useful example: tcpdump udp port 161 –i eth0 –vvv –A The preceding command will produce the following output: Without going too much into detail about the SNMP packet structure, looking through the printable strings captured, it's usually pretty easy to see the community string. You may also want to look at building a more comprehensive packet-capturing tool using something such as Scapy, which is available in Kali Linux versions.
Read more
  • 0
  • 0
  • 5849

article-image-active-directory-design-principles-part-2-2
Packt
30 Sep 2009
12 min read
Save for later

Active Directory Design Principles: Part 2

Packt
30 Sep 2009
12 min read
Design your Active Directory In most corporations and large organizations, there are people with job titles such as "Network Architect", "Windows Server Configuration Owner" or "Network Designer". These people do not have these titles just for fun. In large organizations, there is an actual need for people whose sole purpose is to design or optimize the networking topology according to how technology progresses. This is also valid for people who work in the Security and the actual Business Solutions sections of large corporations. There are always new ways of doing things and new designs surfacing in the IT world, and those people need to stay on top of their respective fields. If you are a medium to small-sized company, you can probably combine all of those roles into one person or have several roles distributed over few people. This is especially true for Windows Server architecture and Active Directory. When designing your Active Directory, you need to really open your mind and focus on the future. A bit of clairvoyance doesn't hurt here. The problem with an Active Directory design for a medium to large-sized company is actually two-fold. One, you need to be able to make your design scalable in the future and two, you need to be able to migrate to your new architecture with the least user impact. In order to make this a bit easier, here are two small checklists. The first one contains things to consider when designing a global AD, and the second one is a checklist of things to consider when finalizing the design, or when migrating. These points are not in any particular order as they should all be considered. Checklist When Designing a New AD Is the name future-proof (DNS)? Do you own the DNS name? How many users are in each office? What's the bandwidth available between offices? Is it enough for smaller offices to authenticate in a central location? Who will administer the AD? Who will perform day-to-day tasks (password resets, user and computer account creation)? Are there plans to build on the AD with additional services, such as Exchange, SharePoint etc.? Which DCs will be Global Catalog Servers? Where will the FSMO roles be located? Will the new design support all the current business functions? If not at the beginning, will there be a transition period and if so how long? Have you cleared this with business? Will all the third-party applications still work with this design? Checklist When Finalizing the Design or When Migrating to an AD Have you chosen a design? If yes, have you considered the model carefully, taking into account future growth? Is the DNS name available and is it future-proof? Have you calculated the appropriate number of DCs? Have you considered DC failover and the network strain? Is the number of administrators and their roles clearly defined? Do you have processes for change mangement in place? If no, should you? Do you have back-up designs and solutions in place where it matters (hub sites and data centers)? Is your staff trained or will there be training to bring them up-to-date with the new methodologies? How significant will the user impact be? Are mechanisms in place to inform the users of the coming changes? Are all networked applications accounted for? Have service accounts been assigned and possibly consolidated across the enterprise? Is a realistic implementation schedule in place? Has it been approved and discussed? Naming standards Before you begin to design anything, you need to make sure that you have a naming standard for everything across your entire organization. If this is missing, and everyone just decides what to name the GPO and computers, how usernames are formatted, how service accounts are named, etc., then you will never have a proper structure. Username and service account naming There are endless ways of naming your user accounts and you probably already have one or another in place. If, however, you have a multitude of different ways because of acquisition, or autonomy of certain offices in the past, defining a universal way of naming user accounts is crucial. This will not only help you with administration, but also with deploying services across your organization. If you name the service accounts using a standard, every administrator knows exactly what the account is for. When you name the users in a standard way, processes regarding user administration can be very streamlined. You should also consider the lockdown of service accounts, for example by defining what machine they can authenticate from and what they can access. The same goes for user accounts. Group policy naming A common thing for administrators to do is name group policies after what they see as the most logical thing at that moment. You should have clear guidelines of how to name GPO's so that they make sense even to a new person. "Internet Explorer Test 3" as a GPO name is not anything that you could guess what it includes, or to whom it applies. Naming conventions are overlooked a lot of the time, not only for GPOs but for many administrative things that do not seem to matter at the time. In short, the naming of the GPO is important so that you can immediately know what the policy does and who it applies to. This makes troubleshooting much easier. The following figure shows GPOs named with a little bit more sense, as it shows that the policy is global and that the settings that these policies set are for users and computers. Design with scalability in mind Whenever you read books or white papers about Active Directory, they mention the amazing scalability of Active Directory, its security features, and the redundancy. Active Directory was coded from the ground up with mechanisms that make it easy to add or remove domain controllers. With this ability, features are built in to failover to the next domain controller in case of a failure in one of them. The client never really knows about this. On paper, this is a great thing and reduces the administrative overhead. In practice, it is just as good. Large corporations can have Active Directory structures that work so perfectly that the administrators really do not have to worry about anything regarding stability. This applies even when there are more then 30,000 users over several countries and almost twice as many computer accounts. As the saying goes: "Behind every strong man stands a strong woman". The same goes for Active Directory: "Behind every perfectly working Active Directory, there is a good architect". Microsoft's recommendation is to have 150 users per domain controller. This is a good recommendation yet you do not need to take it 100% verbatim. In any site with 150-200 users, you should have at least two domain controllers. This is not meant as an issue of scalability but more of a failover issue. In a case of 400 users for example, Microsoft recommends, according to their white paper, three domain controllers. For 400 users in a single site that is a lot. Considering that the heavy load on the domain controllers will be in the morning when people arrive and log in, and after lunch when people log in again, most of the time the domain controllers will sit idle. In this case, the recommendation is rather to spend a bit extra on more RAM and more CPU power than on an extra machine. If your network is well-designed and your domain controllers have a little more power, you can load a relatively large number of users onto them. It is not unheard of to have over 600 users per domain controller in a large organization and the average load during the day is around 40%. It rises during peak hours of logon and logoff, as is expected, but quite a lot of time they are almost idle. The key factor here is memory and CPU. If the amount of RAM you have is twice the size of your Active Directory database, the database will be loaded completely into memory by the domain controller. This, combined with a server-class CPU such as XEON or Opteron, will reduce the processing time during authentication per user to fractions of a second. If you could only authenticate five people per second on a domain controller, it would take you two minutes to authenticate 600 users. And 600 users do not all arrive at work at the same time and log in at the exact same time. Scalability in Active Directory is achieved through the distributed model that it builds on. Every domain controller is writable in the AD and holds more-or-less a complete copy of the directory. When changes occur in one site on one DC, these changes are then replicated out to all the others. This architecture is radically different from Windows NT 4, where there was a primary domain controller and many backup domain controllers. There is only one problem with this set-up, and this becomes apparent when you have a lot of distributed domain controllers and a lot of sites. If you do not invest time into the design of the sites and site links, you can cause a lot of damage and a lot of unnecessary traffic in a very short time. Site links are there to provide ways of controlling when and how the Active Directory is replicated to other domain controllers. You do not want to end up replicating a 2GB database during business hours over a 2 Mbit link. However, if you do not properly document and implement a good replication design, unnecessary delays will happen. You will then have the nice job of finding out where the replication went wrong, and depending on the number of sites you have, this can be a non-trivial task. The following figure shows different replication schedules and site links that make it quite normal for one site to have a six to eight hour delayed version of the Active Directory. Replication schedules are not difficult to design and implement, but do require a bit of time and input from other sources. Remember, because Active Directory is so distributed, the site with the slowest site link and the slowest replication will have the most outdated version of Active Directory. It is recommended that in case something unexpected happens, such as dismissing an employee in a remote office, you force-replicate between the main site and that site-as soon as the changes are made. If the person is leaving in two week's time, set his or her account on the date they are scheduled to leave and then verify that the data has been replicated after this date. Flexible Single Master Operation Roles (FSMO) When you design your topology, you have to be aware of the Flexible Single Master Operation Roles (FSMO) and place them accordingly. FSMO roles are roles that only one server in an Active Directory can have. These roles, while not apparent immediately and not needed all the time, are very important, and some of them are very crucial. There are five FSMO roles and they must be present in an Active Directory. Three of these roles are domain-specific, which means that in every domain in an AD forest, they have to be present. The other two are forest-specific and therefore one of each needs to be present in each of your AD forests. See the table below for a few summary of roles and where they belong: Name of the role Where is it needed RID Master (Relative ID Master) In each domain Infrastructure Master In each domain PDC Emulater In each domain Schema Master In each forest Domain name Master In each forest Each role does different things and in order to understand the importance of the roles, a full description of each role, and the steps you need to take to see which server has what role, is given below: Relative ID Master (RID Master) This role allocates security RIDs to DCs within a domain. The DCs use the allocated RIDs and in turn allocate them to security principals, such as users and computers, as they are added. The server that has this role also manages the movement of objects between domains. It monitors all of the pools allocated to all of the DCs within a domain and in doing so allocates more RIDs where needed, to prevent these pools from becoming exhausted, which would result in the inability to create new user or computer accounts. Infrastructure Manager The server having this role maintains security Globally Unique Identifiers (GUIDs) and Distinguished Names (DNs) for all objects that are referenced across different domains. However, its most common task is to update user and group links. PDC Emulator This is a crucial role, not only because it emulates a Primary Domain Controller for Windows NT, but because other DCs look at the PDC as the primary source for confirmation of authentication, and it is the most trusted source for time within a domain. To change any of the three domain-specific roles, open Active Directory Users and Computers, right-click on the domain name and click on Operations Masters. You will then get the following screen where you can assign the roles in your domain. Schema Master The server having this role maintains all schema information and all modifications to the schema. The schema in a forest determines what types of objects are permitted and what types of attributes an object can have. A typical scenario for this role would be an installation or deployment of Exchange, or an upgrade from Windows 2000 to 2003, because these operations contain schema modifications.
Read more
  • 0
  • 0
  • 5845
article-image-linux-shell-script-monitoring-activities
Packt
28 Jan 2011
8 min read
Save for later

Linux Shell Script: Monitoring Activities

Packt
28 Jan 2011
8 min read
Linux Shell Scripting Cookbook Solve real-world shell scripting problems with over 110 simple but incredibly effective recipes Master the art of crafting one-liner command sequence to perform tasks such as text processing, digging data from files, and lot more Practical problem solving techniques adherent to the latest Linux platform Packed with easy-to-follow examples to exercise all the features of the Linux shell scripting language Part of Packt's Cookbook series: Each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible.    Disk usage hacks Disk space is a limited resource. We frequently perform disk usage calculation on hard disks or any storage media to find out the free space available on the disk. When free space becomes scarce, we will need to find out large-sized files that are to be deleted or moved in order to create free space. Disk usage manipulations are commonly used in shell scripting contexts. This recipe will illustrate various commands used for disk manipulations and problems where disk usages can be calculated with a variety of options. Getting ready df and du are the two significant commands that are used for calculating disk usage in Linux. The command df stands for disk free and du stands for disk usage. Let's see how we can use them to perform various tasks that involve disk usage calculation. How to do it... To find the disk space used by a file (or files), use: $ du FILENAME1 FILENAME2 . . For example: $ du file.txt 4 The result is, by default, shown as size in bytes. In order to obtain the disk usage for all files inside a directory along with the individual disk usage for each file showed in each line, use: $ du -a DIRECTORY -a outputs results for all files in the specified directory or directories recursively. Running du DIRECTORY will output a similar result, but it will show only the size consumed by subdirectories. However, they do not show the disk usage for each of the files. For printing the disk usage by files, -a is mandatory. For example: $  du -a test 4  test/output.txt 4  test/process_log.sh 4  test/pcpu.sh 16  test An example of using du DIRECTORY is as follows: $ du test 16  test There's more... Let's go through additional usage practices for the du command. Displaying disk usage in KB, MB, or Blocks By default, the disk usage command displays the total bytes used by a file. A more human-readable format is when disk usage is expressed in standard units KB, MB, or GB. In order to print the disk usage in a display-friendly format, use –h as follows: du -h FILENAME For example: $ du -sh test/pcpu.sh 4.0K  test/pcpu.sh # Multiple file arguments are accepted Or: # du -h DIRECTORY $ du -h hack/ 16K  hack/ Finding the 10 largest size files from a given directory Finding large-size files is a regular task we come across. We regularly require to delete those huge size files or move them. We can easily find out large-size files using du and sort commands. The following one-line script can achieve this task: $ du -ak SOURCE_DIR | sort -nrk 1 | head Here -a specifies all directories and files. Hence du traverses the SOURCE_DIR and calculates the size of all files. The first column of the output contains the size in Kilobytes since -k is specified and the second column contains the file or folder name. sort is used to perform numerical sort with column 1 and reverse it. head is used to parse the first 10 lines from the output. For example: $ du -ak /home/slynux | sort -nrk 1 | head -n 4 50220 /home/slynux 43296 /home/slynux/.mozilla 43284 /home/slynux/.mozilla/firefox 43276 /home/slynux/.mozilla/firefox/8c22khxc.default One of the drawbacks of the above one-liner is that it includes directories in the result. However, when we need to find only the largest files and not directories we can improve the one-liner to output only the large-size files as follows: $ find . -type f -exec du -k {} ; | sort -nrk 1 | head We used find to filter only files to du rather than allow du to traverse recursively by itself. Calculating execution time for a command While testing an application or comparing different algorithms for a given problem, execution time taken by a program is very critical. A good algorithm should execute in minimum amount of time. There are several situations in which we need to monitor the time taken for execution by a program. For example, while learning about sorting algorithms, how do you practically state which algorithm is faster? The answer to this is to calculate the execution time for the same data set. Let's see how to do it. How to do it... time is a command that is available with any UNIX-like operating systems. You can prefix time with the command you want to calculate execution time, for example: $ time COMMAND The command will execute and its output will be shown. Along with output, the time command appends the time taken in stderr. An example is as follows: $ time ls test.txt next.txt real    0m0.008s user    0m0.001s sys     0m0.003s It will show real, user, and system times for execution. The three different times can be defined as follows: Real is wall clock time—the time from start to finish of the call. This is all elapsed time including time slices used by other processes and the time that the process spends when blocked (for example, if it is waiting for I/O to complete). User is the amount of CPU time spent in user-mode code (outside the kernel) within the process. This is only the actual CPU time used in executing the process. Other processes and the time that the process spends when blocked do not count towards this figure. Sys is the amount of CPU time spent in the kernel within the process. This means executing the CPU time spent in system calls within the kernel, as opposed to library code, which is still running in the user space. Like 'user time', this is only the CPU time used by the process. An executable binary of the time command is available at /usr/bin/time as well as a shell built-in named time exists. When we run time, it calls the shell built-in by default. The shell built-in time has limited options. Hence, we should use an absolute path for the executable (/usr/bin/time) for performing additional functionalities. We can write this time statistics to a file using the -o filename option as follows: $ /usr/bin/time -o output.txt COMMAND The filename should always appear after the –o flag. In order to append the time statistics to a file without overwriting, use the -a flag along with the -o option as follows: $ /usr/bin/time -a -o output.txt COMMAND We can also format the time outputs using format strings with the -f option. A format string consists of parameters corresponding to specific options prefixed with %. The format strings for real time, user time, and sys time are as follows: Real time - %e f User - %U f sys - %S By combining parameter strings, we can create formatted output as follows: $ /usr/bin/time -f "FORMAT STRING" COMMAND For example: $ /usr/bin/time -f "Time: %U" -a -o timing.log uname Linux Here %U is the parameter for user time. When formatted output is produced, the formatted output of the command is written to the standard output and the output of the COMMAND, which is timed, is written to standard error. We can redirect the formatted output using a redirection operator (>) and redirect the time information output using the (2>) error redirection operator. For example: $ /usr/bin/time -f "Time: %U" uname> command_output.txt 2>time.log $ cat time.log Time: 0.00 $ cat command_output.txt Linux Many details regarding a process can be collected using the time command. The important details include, exit status, number of signals received, number of context switches made, and so on. Each parameter can be displayed by using a suitable format string. The following table shows some of the interesting parameters that can be used: For example, the page size can be displayed using the %Z parameters as follows: $ /usr/bin/time -f "Page size: %Z bytes" ls> /dev/null Page size: 4096 bytes Here the output of the timed command is not required and hence the standard output is directed to the /dev/null device in order to prevent it from writing to the terminal.  
Read more
  • 0
  • 0
  • 5844

article-image-basic-operations-elasticsearch
Packt
16 Jan 2017
10 min read
Save for later

Basic Operations of Elasticsearch

Packt
16 Jan 2017
10 min read
In this article by Alberto Maria Angelo Paro, the author of the book ElasticSearch 5.0 Cookbook - Third Edition, you will learn the following recipes: Creating an index Deleting an index Opening/closing an index Putting a mapping in an index Getting a mapping (For more resources related to this topic, see here.) Creating an index The first operation to do before starting indexing data in Elasticsearch is to create an index--the main container of our data. An index is similar to the concept of database in SQL, a container for types (tables in SQL) and documents (records in SQL). Getting ready To execute curl via the command line you need to install curl for your operative system. How to do it... The HTTP method to create an index is PUT (but also POST works); the REST URL contains the index name: http://<server>/<index_name> For creating an index, we will perform the following steps: From the command line, we can execute a PUT call: curl -XPUT http://127.0.0.1:9200/myindex -d '{ "settings" : { "index" : { "number_of_shards" : 2, "number_of_replicas" : 1 } } }' The result returned by Elasticsearch should be: {"acknowledged":true,"shards_acknowledged":true} If the index already exists, a 400 error is returned: { "error" : { "root_cause" : [ { "type" : "index_already_exists_exception", "reason" : "index [myindex/YJRxuqvkQWOe3VuTaTbu7g] already exists", "index_uuid" : "YJRxuqvkQWOe3VuTaTbu7g", "index" : "myindex" } ], "type" : "index_already_exists_exception", "reason" : "index [myindex/YJRxuqvkQWOe3VuTaTbu7g] already exists", "index_uuid" : "YJRxuqvkQWOe3VuTaTbu7g", "index" : "myindex" }, "status" : 400 } How it works... Because the index name will be mapped to a directory on your storage, there are some limitations to the index name, and the only accepted characters are: ASCII letters [a-z] Numbers [0-9] point ".", minus "-", "&" and "_" During index creation, the replication can be set with two parameters in the settings/index object: number_of_shards, which controls the number of shards that compose the index (every shard can store up to 2^32 documents) number_of_replicas, which controls the number of replica (how many times your data is replicated in the cluster for high availability)A good practice is to set this value at least to 1. The API call initializes a new index, which means: The index is created in a primary node first and then its status is propagated to all nodes of the cluster level A default mapping (empty) is created All the shards required by the index are initialized and ready to accept data The index creation API allows defining the mapping during creation time. The parameter required to define a mapping is mapping and accepts multi mappings. So in a single call it is possible to create an index and put the required mappings. There's more... The create index command allows passing also the mappings section, which contains the mapping definitions. It is a shortcut to create an index with mappings, without executing an extra PUT mapping call: curl -XPOST localhost:9200/myindex -d '{ "settings" : { "number_of_shards" : 2, "number_of_replicas" : 1 }, "mappings" : { "order" : { "properties" : { "id" : {"type" : "keyword", "store" : "yes"}, "date" : {"type" : "date", "store" : "no" , "index":"not_analyzed"}, "customer_id" : {"type" : "keyword", "store" : "yes"}, "sent" : {"type" : "boolea+n", "index":"not_analyzed"}, "name" : {"type" : "text", "index":"analyzed"}, "quantity" : {"type" : "integer", "index":"not_analyzed"}, "vat" : {"type" : "double", "index":"no"} } } } }' Deleting an index The counterpart of creating an index is deleting one. Deleting an index means deleting its shards, mappings, and data. There are many common scenarios when we need to delete an index, such as: Removing the index to clean unwanted/obsolete data (for example, old Logstash indices). Resetting an index for a scratch restart. Deleting an index that has some missing shard, mainly due to some failures, to bring back the cluster in a valid state (if a node dies and it's storing a single replica shard of an index, this index is missing a shard so the cluster state becomes red. In this case, you'll bring back the cluster to a green status, but you lose the data contained in the deleted index). Getting ready To execute curl via command line you need to install curl for your operative system. The index created is required to be deleted. How to do it... The HTTP method used to delete an index is DELETE. The following URL contains only the index name: http://<server>/<index_name> For deleting an index, we will perform the steps given as follows: Execute a DELETE call, by writing the following command: curl -XDELETE http://127.0.0.1:9200/myindex We check the result returned by Elasticsearch. If everything is all right, it should be: {"acknowledged":true} If the index doesn't exist, a 404 error is returned: { "error" : { "root_cause" : [ { "type" : "index_not_found_exception", "reason" : "no such index", "resource.type" : "index_or_alias", "resource.id" : "myindex", "index_uuid" : "_na_", "index" : "myindex" } ], "type" : "index_not_found_exception", "reason" : "no such index", "resource.type" : "index_or_alias", "resource.id" : "myindex", "index_uuid" : "_na_", "index" : "myindex" }, "status" : 404 } How it works... When an index is deleted, all the data related to the index is removed from disk and is lost. During the delete processing, first the cluster is updated, and then the shards are deleted from the storage. This operation is very fast; in a traditional filesystem it is implemented as a recursive delete. It's not possible restore a deleted index, if there is no backup. Also calling using the special _all index_name can be used to remove all the indices. In production it is good practice to disable the all indices deletion by adding the following line to Elasticsearch.yml: action.destructive_requires_name:true Opening/closing an index If you want to keep your data, but save resources (memory/CPU), a good alternative to delete indexes is to close them. Elasticsearch allows you to open/close an index to put it into online/offline mode. Getting ready To execute curl via the command line you need to install curl for your operative system. How to do it... For opening/closing an index, we will perform the following steps: From the command line, we can execute a POST call to close an index using: curl -XPOST http://127.0.0.1:9200/myindex/_close If the call is successful, the result returned by Elasticsearch should be: {,"acknowledged":true} To open an index, from the command line, type the following command: curl -XPOST http://127.0.0.1:9200/myindex/_open If the call is successful, the result returned by Elasticsearch should be: {"acknowledged":true} How it works... When an index is closed, there is no overhead on the cluster (except for metadata state): the index shards are switched off and they don't use file descriptors, memory, and threads. There are many use cases when closing an index: Disabling date-based indices (indices that store their records by date), for example, when you keep an index for a week, month, or day and you want to keep online a fixed number of old indices (that is, two months) and some offline (that is, from two months to six months). When you do searches on all the active indices of a cluster and don't want search in some indices (in this case, using alias is the best solution, but you can achieve the same concept of alias with closed indices). An alias cannot have the same name as an index When an index is closed, calling the open restores its state. Putting a mapping in an index We saw how to build mapping by indexing documents. This recipe shows how to put a type mapping in an index. This kind of operation can be considered as the Elasticsearch version of an SQL created table. Getting ready To execute curl via the command line you need to install curl for your operative system. How to do it... The HTTP method to put a mapping is PUT (also POST works). The URL format for putting a mapping is: http://<server>/<index_name>/<type_name>/_mapping For putting a mapping in an index, we will perform the steps given as follows: If we consider the type order, the call will be: curl -XPUT 'http://localhost:9200/myindex/order/_mapping' -d '{ "order" : { "properties" : { "id" : {"type" : "keyword", "store" : "yes"}, "date" : {"type" : "date", "store" : "no" , "index":"not_analyzed"}, "customer_id" : {"type" : "keyword", "store" : "yes"}, "sent" : {"type" : "boolean", "index":"not_analyzed"}, "name" : {"type" : "text", "index":"analyzed"}, "quantity" : {"type" : "integer", "index":"not_analyzed"}, "vat" : {"type" : "double", "index":"no"} } } }' In case of success, the result returned by Elasticsearch should be: {"acknowledged":true} How it works... This call checks if the index exists and then it creates one or more type mapping as described in the definition. During mapping insert if there is an existing mapping for this type, it is merged with the new one. If there is a field with a different type and the type could not be updated, an exception expanding fields property is raised. To prevent an exception during the merging mapping phase, it's possible to specify the ignore_conflicts parameter to true (default is false). The put mapping call allows you to set the type for several indices in one shot; list the indices separated by commas or to apply all indexes using the _all alias. There's more… There is not a delete operation for mapping. It's not possible to delete a single mapping from an index. To remove or change a mapping you need to manage the following steps: Create a new index with the new/modified mapping Reindex all the records Delete the old index with incorrect mapping Getting a mapping After having set our mappings for processing types, we sometimes need to control or analyze the mapping to prevent issues. The action to get the mapping for a type helps us to understand structure or its evolution due to some merge and implicit type guessing. Getting ready To execute curl via command-line you need to install curl for your operative system. How to do it… The HTTP method to get a mapping is GET. The URL formats for getting mappings are: http://<server>/_mapping http://<server>/<index_name>/_mapping http://<server>/<index_name>/<type_name>/_mapping To get a mapping from the type of an index, we will perform the following steps: If we consider the type order of the previous chapter, the call will be: curl -XGET 'http://localhost:9200/myindex/order/_mapping?pretty=true' The pretty argument in the URL is optional, but very handy to pretty print the response output. The result returned by Elasticsearch should be: { "myindex" : { "mappings" : { "order" : { "properties" : { "customer_id" : { "type" : "keyword", "store" : true }, … truncated } } } } } How it works... The mapping is stored at the cluster level in Elasticsearch. The call checks both index and type existence and then it returns the stored mapping. The returned mapping is in a reduced form, which means that the default values for a field are not returned. Elasticsearch stores only not default field values to reduce network and memory consumption. Retrieving a mapping is very useful for several purposes: Debugging template level mapping Checking if implicit mapping was derivated correctly by guessing fields Retrieving the mapping metadata, which can be used to store type-related information Simply checking if the mapping is correct If you need to fetch several mappings, it is better to do it at index level or cluster level to reduce the numbers of API calls. Summary We learned how to manage indices and perform operations on documents. We'll discuss different operations on indices such as create, delete, update, open, and close. These operations are very important because they allow better define the container (index) that will store your documents. The index create/delete actions are similar to the SQL create/delete database commands. Resources for Article: Further resources on this subject: Elastic Stack Overview [article] Elasticsearch – Spicing Up a Search Using Geo [article] Downloading and Setting Up ElasticSearch [article]
Read more
  • 0
  • 0
  • 5843

article-image-manipulating-images-javafx
Packt
25 Aug 2010
4 min read
Save for later

Manipulating Images with JavaFX

Packt
25 Aug 2010
4 min read
(For more resources on Java, see here.) One of the most celebrated features of JavaFX is its inherent support for media playback. As of version 1.2, JavaFX has the ability to seamlessly load images in different formats, play audio, and play video in several formats using its built-in components. To achieve platform independence and performance, the support for media playback in JavaFX is implemented as a two-tiered strategy: Platform-independent APIs—the JavaFX SDK comes with a media API designed to provide a uniform set of interfaces to media functionalities. Part of the platform-independence offerings include a portable codec (On2's VP6), which will play on all platforms where JavaFX media playback is supported. Platform-dependent implementations—to boost media playback performance, JavaFX also has the ability to use the native media engine supported by the underlying OS. For instance, playback on the Windows platform may be rendered by the Windows DirectShow media engine (see next recipe). This two-part article shows you how to use the supported media rendering components, including ImageView, MediaPlayer, and MediaView. These components provide high-level APIs that let developers create applications with engaging and interactive media content. Accessing media assets You may have seen the use of variable __DIR__ when accessing local resources, but may not fully know about its purpose and how it works. So, what does that special variable store? In this recipe, we will explore how to use the __DIR__ special variable and other means of loading resources locally or remotely. Getting ready The concepts presented in this recipe are used widely throughout the JavaFX application framework when pointing to resources. In general, classes that point to a local or remote resource uses a string representation of a URL where the resource is stored. This is especially true for the ImageView and MediaPlayer classes discussed in this article. How to do it... This recipe shows you three ways of creating a URL to point to a local or remote resource used by a JavaFX application. The full listing of the code presented here can be found in ch05/source-code/src/UrlAccess.fx. Using the __DIR__ pseudo-variable to access assets as packaged resources: var resImage = "{__DIR__}image.png"; Using a direct reference to a local file: var localImage = "file:/users/home/vladimir/javafx/ch005/source-code/src/image.png"; Using a URL to access a remote file: var remoteImage = "http://www.flickr.com/3201/2905493571_a6db13ce1b_d.jpg" How it works... Loading media assets in JavaFX requires the use of a well-formatted URL that points to the location of the resources. For instance, both the Image and the Media classes (covered later in this article series) require a URL string to locate and load the resource to be rendered. The URL must be an absolute path that specifies the fully-realized scheme, device, and resource location. The previous code snippets show the following three ways of accessing resources in JavaFX: __DIR__ pseudo-variable—often, you will see the use of JavaFX's pseudo variable __DIR__, used when specifying the location of a resource. It is a special variable that stores the String value of the directory where the executing class that referenced __DIR__ is located. This is valuable, especially when the resource is embedded in the application's JAR file. At runtime, __DIR__ stores the location of the resource in the JAR file, making it accessible for reading as a stream. In the previous code, for example, the expression {__DIR__}image.png explodes as jar:file:/users/home/vladimir/javafx/ch005/source-code/dist/source-code.jar!/image.png. Direct reference to local resources—when the application is deployed as a desktop application, you can specify the location of your resources using URLs that provides the absolute path to where the resources are located. In our code, we use file:/users/home/vladimir/javafx/ch005/source-code/src/image.png as the absolute fully qualified path to the image file image.png. Direct reference to remote resources—finally, when loading media assets, you are able to specify the path of a fully-qualified URL to a remote resource using HTTP. As long as there are no subsequent permissions required, classes such as Image and Media are able to pull down the resource with no problem. For our code, we use a URL to a Flickr image http://www.flickr.com/3201/2905493571_a6db13ce1b_d.jpg. There's more... Besides __DIR__, JavaFX provides the __FILE__ pseudo variable as well. As you may well guess, __FILE__ resolves to the fully qualified path of the of the JavaFX script file that contains the __FILE__ pseudo variable. At runtime, when your application is compiled, this will be the script class that contains the __FILE__ reference.
Read more
  • 0
  • 0
  • 5839
article-image-social-networks
Packt
29 Oct 2013
15 min read
Save for later

Social Networks

Packt
29 Oct 2013
15 min read
(For more resources related to this topic, see here.) One window to rule them all Since we want to give our users the ability to post their messages on multiple social networks at once, it makes perfect sense to keep our whole application in a single window. It will be comprised of the following sections: The top section of the window will contain labels and a text area for message input. The text area will be limited to 140 characters in order to comply with Twitter's message limitation. As the user types his or her message, a label showing the number of characters will be updated. The bottom section of the window will use an encapsulating view that will contain multiple image views. Each image view will represent a social network to which the application will post the messages (in our case, Twitter and Facebook). But we can easily add more networks that will have their representation in this section. Each image view acts as a toggle button in order to select if the message will be sent to a particular social network or not. Finally, in the middle of those two sections, we will add a single button that will be used to publish the message from the text area. Code while it is hot! With our design in hand, we can now move on to create our user interface. Our entire application will be contained in a single window, so this is the first thing we will create. We will give it a title as well as a linear background gradient that changes from purple at the top to black at the bottom of the screen. Since we will add other components to it, we will keep its reference in the win variable: var win = Ti.UI.createWindow({ title: 'Unified Status', backgroundGradient: { type: 'linear', startPoint: { x: '0%', y: '0%' }, endPoint: { x: '0%', y: '100%' }, colors: [ { color: '#813eba'}, { color: '#000' } ] } }); The top section We will then add a new white label at the very top of the window. It will span 90% of the window's width, have a bigger font than other labels, and will have its text aligned to the left. Since this label will never be accessed later on, we will invoke our createLabel function right into the add function of the window object: win.add(Ti.UI.createLabel({ text: 'Post a message', color: '#fff', top: 4, width: '90%', textAlign: Ti.UI.TEXT_ALIGNMENT_LEFT, font: { fontSize: '22sp' } })); We will now move on to create our text area where our users will enter their messages. It will be placed right under the label previously created, occupy 90% of the screen's width, have a slightly bigger font, and have a thick, rounded, dark border. It will also be limited to 140 characters. It is also important that we don't forget to add this newly created object to our main window: var txtStatus = Ti.UI.createTextArea({ top: 37, width: '90%', height: 100, color: '#000', maxLength: 140, borderWidth: 3, borderRadius: 4, borderColor: '#401b60', font: { fontSize: '16sp' } }); win.add(txtStatus); The second label that will complement our text area will be used to indicate how many characters are currently present in the user's message. So, we will now create a label just underneath the text area and assign it a default text value. It will span 90% of the screen's width and have its text aligned to the right. Since this label will be updated dynamically when the text area's value changes, we will keep its reference in a variable named lblCount. As we did with our previous UI components, we will add our label to our main window using the following code: var lblCount = Ti.UI.createLabel({ text: '0/140', top: 134, width: '90%', color: '#fff', textAlign: Ti.UI.TEXT_ALIGNMENT_RIGHT }); win.add(lblCount); The last control from the top section will be our Post button. It will be placed right under the text area and centered horizontally using the following code: var btnPost = Ti.UI.createButton({ title: 'Post', top: 140, width: 150 }); win.add(btnPost); By not specifying any left or right property, the component is automatically centered. This is pretty useful to keep in mind while designing our user interfaces, as it frees us from having to do calculations in order to center something on the screen. Staying within the limits Even though the text area's maxLength property will ensure that the message length will not exceed the limitation we have set, we need to give our users feedback as they are typing their message. To achieve this, we will add an event listener on the change event of our text area. Every time; the text area's content changes, we will update the lblCount label with the number of characters our message contains: txtStatus.addEventListener('change', function(e) { lblCount.text = e.value.length + '/140'; We will also add a condition to check if our user's message is close to reaching its limit. If that is the case, we will change the label's color to red, if not, it will return to its original color: if (e.value.length > 120) { lblCount.color = 'red'; } else { lblCount.color = 'white' } Our last conditional check will be enabling the Post button only if there is actually a message to be posted. This will prevent our users from posting empty messages: btnPost.enabled = !(e.value.length === 0); }); Setting up our Post button Probably the most essential component in our application would be the Post button. We won't be able to post anything online (yet) by clicking on it, as there are things we will still need to add. We will add an event listener for the click event on the Post button. If the on-screen keyboard is displayed, we will call the blur function of the text area in order to hide it: btnPost.addEventListener('click', function() { txtStatus.blur(); Also, we will reset the value to the text area and the character count on the label, so that the interface is ready to enter a new message: txtStatus.value = ''; lblCount.text = '0/140'; }); The bottom section With all our message input mechanisms in place, we will now move on to our bottom section. All components from this section will be contained in a view that will be placed at the bottom of the screen. It will span 90% of the screen's width, and its height will adapt to its content. We will store its reference in a variable named bottomView for later use: var bottomView = Ti.UI.createView({ bottom: 4, width: '90%', height: Ti.UI.SIZE }); We will then create our toggle switches for each social network that our application interacts with. Since we want something sexier than regular switch components, we will create our own switch using a regular image view. Our first image view will be used to toggle the use of Facebook. It will have a dark blue background (similar to Facebook's logo) and will have a background image representing Facebook's logo with a gray background, so that it appears disabled. It will be positioned to the left of its parent view, and will have a borderRadius value of 4 in order to give it a rounded aspect. We will keep its reference in the fbView variable and then add this same image view to our bottom view using the following code: var fbView = Ti.UI.createImageView({ backgroundColor: '#3B5998', image: 'images/fb-logo-disabled.png', borderRadius: 4, width: 100, left: 10, height: 100 }); bottomView.add(fbView); We will create a similar image view (in almost every way), but this time for Twitter. So the background color and the image will be different. Also, it will be positioned to the right of our container view. We will store its reference in the twitView variable and then add it to our bottom view using the following code: var twitView = Ti.UI.createImageView({ backgroundColor: '#9AE4E8', image: 'images/twitter-logo-disabled.png', borderRadius: 4, width: 100, right: 10, height: 100 }); bottomView.add(twitView); Last but not the least, it is imperative that we do not forget to add our bottomView container object into our window. Also, we will open the window so that our users can interact with it using the following code: win.add(bottomView); win.open(); What if the user rotates the device? At this stage, if our user were to rotate the device (to landscape), nothing would happen on the screen. The reason behind this is because we have not taken any action to make our application compatible with the landscape mode. In many cases, this would require some changes to how the user interface is created depending on the orientation. But since our application is fairly simple, and most of our layout relies on percentages, we can activate the landscape mode without any modification to our code. To activate the landscape mode, we will update the orientations section from our tiapp.xml configuration file. It is mandatory to have at least one orientation present in this section (it doesn't matter which one it is). We want our users to be able to use the application, no matter how they hold their device: <iphone> <orientations device="iphone"> <orientation>Ti.UI.PORTRAIT</orientation> <orientation>Ti.UI.UPSIDE_PORTRAIT</orientation> <orientation>Ti.UI.LANDSCAPE_LEFT</orientation> <orientation>Ti.UI.LANDSCAPE_RIGHT</orientation> </orientations> </iphone> By default, no changes are required for Android applications since the default behavior supports orientation changes. There are, of course, ways to limit orientation in the manifest section, but this subject falls out of this article's scope. See it in action We have now implemented all the basic user interface. We can now test it and see if it behaves as we anticipated. We will click on the Run button from the App Explorer tab, as we did many times before. We now have our text area at the top with our two big images views at the bottom, each with the social network's logo. We can already test the message entry (with the character counter incrementing) by clicking on the Post button. Now if we rotate the iOS simulator (or the Android emulator), we can see that our layout adapts well to the landscape mode. To rotate the iOS simulator, you need to use the Hardware menu or you can use Cmd-Left and Cmd-Right on the keyboard. If you are using the Android emulator, there is no menu, but you can change the orientation using Ctrl + F12. The reason this all fits so well is because most of our dimensions are done using percentages. That means that our components will adapt and use the available space on the screen. Also, we positioned the bottom view using the bottom property; which meant that it will stick to the bottom of the screen, no matter how tall it is. There is a module for that Since we don't want to interact with the social network through manual asynchronous HTTP requests, we will leverage the Facebook native module provided with Titanium. Since it comes with Titanium SDK, there is no need to download or copy any file. All we need to do is add a reference (one for each target platform), in the modules section of our tiapp.xml file as follows: <modules> <module platform="android">facebook</module> <module platform="iphone">facebook</module> </modules> Also, we need to add the following property at the end of our configuration file, and replace the FACEBOOK_APPID parameter with the application ID that was provided when we created our app online. <property name="ti.facebook.appid">[FACEBOOK_APPID]</property> Why do we have to reference a module even though it comes bundled with the Titanium framework? Mostly, it is to avoid framework bloat; it is safe to assume that most applications developed using Titanium won't require interaction with Facebook. This is the reason for having it in a separate module that can be loaded on demand. Linking our mobile app to our Facebook app With our Facebook module loaded, we will now populate the necessary properties before making any call to the network. We will need to set the appid property in our code; since we have already defined it as a property in our tiapp.xml file, we can access it through the Properties API. This is a neat way to externalize application parameters, thus preventing us to hardcode them in our JavaScript code: fb.appid = Ti.App.Properties.getString('ti.facebook.appid'); We will also set the proper permissions that we will need while interacting with the server. (In this case, we only want to publish messages on the user's wall): fb.permissions = ['publish_actions']; It is important to set the appid and permissions properties before calling the authorize function. This makes sense since we want Facebook to authorize our application with a defined set of permissions from the get-go. Allowing our user to log in and log out at the click of a button We want our users to be able to connect (and disconnect) at their will from one social network, just by pressing the same view on the screen. To achieve this, we will create a function called toggleFacebook that will have a single parameter: function toggleFacebook(isActive) { If we want the function to make the service active, then we will verify if the user is already logged in to Facebook. If not, we will ask Facebook to authorize the application using the function with the same name. If the parameter indicates that we want to make the service inactive, we will log out from Facebook altogether: if (isActive) { if (!fb.loggedin) { fb.authorize(); } } else { fb.logout(); } } Now, all that we need to do is create an event listener on the click event for our Facebook image view and simply toggle between the two states depending whether the user is logged in or not: fbView.addEventListener('click', function() { toggleFacebook(!fb.loggedIn); }); The authorize function prompts the user to log in (if he or she is not already logged in), and authorize his or her application. It kind of makes sense that Facebook requires user validation before delegating the right to post something on his or her behalf. Handling responses from Facebook We have now completely implemented the Facebook login/logout mechanism into our application, but we still need to provide some feedback to our users. The Facebook module provides two event listeners that allow us to track when our user will have logged in or out. In the login event listener, we will check if the user is logged in successfully. If he or she did, we will update the image view's image property with the colored logo. If there was any error during authentication, or if the operation was simply cancelled, we will show an alert, as given in the following code: fb.addEventListener('login', function(e) { if (e.success) { fbView.image = 'images/fb-logo.png'; } else if (e.error) { alert(e.error); } else if (e.cancelled) { alert("Canceled"); } }); In the logout event listener, we will update the image view's image property with the grayed out Facebook logo using the following code: fb.addEventListener('logout', function(e) { fbView.image = 'images/fb-logo-disabled.png'; }); Posting our message on Facebook Since we are now connected to Facebook, and our application is authorized to post, we can now post our messages on this particular social network. To do this, we will create a new function named postFacebookMessage, with a single parameter, and that will be the message string to be posted: function postFacebookMessage(msg) { Inside this function, we will call the requestWithGraphPath function from the Facebook native module. This function can look fairly complex at first glance, but we will go over each parameter in detail. The parameters are as follows: The Graph API path requested (My feed). A dictionary object containing all of the properties required by the call (just the message). The HTTP method used for this call (POST). The callback function invoked when the request completes (this function simply checks the result from the call. In case of error, an alert is displayed). fb.requestWithGraphPath('me/feed', { message: msg }, "POST", function(e) { if (e.success) { Ti.API.info("Success! " + e.result); } else { if (e.error) { alert(e.error); } else { alert("Unknown result"); } } } ); } We will then update the click event handler for the Post button and call the postFacebookMessage function if the user is logged in to Facebook: btnPost.addEventListener('click', function() { if (fb.loggedIn) { postFacebookMessage(txtStatus.value); } ... }); With this, our application can post messages on our user's Facebook wall. Summary In this article, we learned how to create server-side applications on two popular social networking websites. We learned how to interact with those networks in terms of API and authentication. We also learned how to handle device rotation as well as use the native platform setting Windows. Finally, we covered Titanium menus and activities. Resources for Article: Further resources on this subject: Appcelerator Titanium: Creating Animations, Transformations, and Understanding Drag-and-drop [Article] augmentedTi: The application architecture [Article] Basic Security Approaches [Article]
Read more
  • 0
  • 0
  • 5839

article-image-25-useful-extensions-drupal-7-themers
Packt
07 Jun 2011
5 min read
Save for later

25 Useful Extensions for Drupal 7 Themers

Packt
07 Jun 2011
5 min read
Drupal 7 Themes Create new themes for your Drupal 7 site with a clean layout and powerful CSS styling Drupal modules There exist within the Drupal.org site a number of modules that are relevant to your work of theming a site. Some are straightforward tools that make your standard theming tasks easier, others are extensions to Drupal functionality that enable to you do new things, or to do things from the admin interface that normally would require working with the code. The list here is not meant to be comprehensive, but it does list all the key modules that are either presently available for Drupal 7 or at least in development. There are additional relevant modules that are not listed here, as at the time this was written, they showed no signs of providing a Drupal 7 version. Caution One thing to keep in mind here—some of these modules attempt to reduce complex tasks to simple GUI-based admin interfaces. While that is a wonderful and worthy effort, you should be conscious of the fact that sometimes tools of this nature can raise performance and security issues and due to their complexity, sometimes cause conflicts with other modules that also are designed to perform at least part of the functions being fulfilled by the more complex module. As with any new module, test it out locally first and make sure it not only does what you want, but also does not provide any unpleasant surprises. The modules covered in this article include: Administration Menu Chaos Tool Suit Colorbox Conditional Stylesheets Devel @font-your-face Frontpage HTML5 Tools .mobi loader Mobile Theme Nice Menus Noggin Organic Groups Panels Semantic Views Skinr Style Guide Sweaver Taxonomy Theme Theme Developer ThemeKey Views Webform Administration Menu The Administration Menu was a mainstay of many Drupal sites built during the lifespan of Drupal 6.x. With the arrival of Drupal 7, we thought it unlikely we would need the module, as the new toolbar functionality in the core accomplished a lot of the same thing. In the course of writing this, however, we installed Administration Menu and were pleasantly surprised to find that not only can you run the old-style Administration Menu, but they have also now included the option to run a Toolbar-style Administration Menu, as shown in the following screenshot: The Administration Menu Toolbar offers all the options of the default Toolbar plus the added advantage of exposing all the menu options without having to navigate through sub-menus on the overlay. Additionally, you have fast access to clearing the caching, running cron, and disabling the Devel module (assuming you have it installed). A great little tweak to the new Drupal 7 administration interface. View the project at: http://drupal.org/project/admin_menu. Chaos Tool Suite This module provides a collection of APIs and tools to assist developers. Though the module is required by both the Views and Panels modules, discussed elsewhere in this article, it provides other features that also make it attractive. Among the tools to help themers are the Form Wizard, which simplifies the creation of complex forms, and the Dependent widget that allows you to set conditional field visibility on forms. The suite also includes CSS Tools to help cache and sanitize your CSS. Learn more at http://drupal.org/project/ctools. Colorbox The Colorbox module for Drupal provides a jQuery-based lightbox plugin. It integrates the third-party plugin of the same name (http://colorpowered.com/colorbox/). The module allows you to easily create lightboxes for images, forms, and content. The module supports the most commonly requested features, including slideshows, captions, and the preloading of images. Colorbox comes with a selection of styles or you can create your own with CSS. To run this module, you must first download and install the Colorbox plugin from the aforementioned URL. Visit the Colorbox Drupal module project page at: http://drupal.org/project/colorbox. Conditional Stylesheets The module allows themers to easily address cross-browser compatibility issues with Internet Explorer. With this module installed, you can add stylesheets targeting the browser via the theme's .info file, rather than having to modify the template.php file. The module relies on the conditional comments syntax originated by Microsoft. To learn more, visit the project site at http://drupal.org/project/conditional_styles. Devel The Devel module is a suite of tools that are useful to both module and theme developers. The module provides a suite of useful tools and utilities. Among the options it provides: Auto-generate content, menus, taxonomies, and users Print summaries of DB queries Print arrays Log performance Summaries of node access The module is also a prerequisite to the Theme Developer module, discussed later in this article. Learn more: http://drupal.org/project/devel. @font-your-face @font-your-face provides an admin interface for browsing and applying web fonts to your Drupal themes. The module employs the CSS @font-face syntax and draws upon a variety of online font resources, including Google Fonts, Typekit. com, KERNEST, and others. The system automatically loads fonts from the selected sources and you can apply them to the styles you designate—without having to manually edit the stylesheets. It's easy-to-use and has the potential to change the way you select and use fonts on your websites. @font-your-face requires the Views module to function. Learn more at the project site: http://drupal.org/project/fontyourface. Frontpage This module serves a very specific purpose—it allows you to designate, from the admin interface, different front pages for anonymous and authenticated users. Though you can accomplish the same thing through use of $classes and a bit of work, the module makes it possible for anyone to set this up without having to resort to coding. Visit the project site at http://drupal.org/project/frontpage.
Read more
  • 0
  • 0
  • 5839
Modal Close icon
Modal Close icon