Kexi in Use
Listing 1. Facebook E-mail Import Script
// This script will import data from exported emails
// into the facebook_stats table
include("qt.core");
include("qt.gui");
var statsFile = new QFile("/home/piggz/kexi_fb/updates.mbox");
var stat_date;
var new_fans;
var new_posts;
var visits;
var total_fans;
var idx;
var conn = Kexi.getConnection();
var table = conn.tableSchema("facebook_stats");
if (statsFile.open(QIODevice.ReadOnly)) {
var ts = new QTextStream(statsFile);
var i = 0;
while (!ts.atEnd()) {
// Process the file line by line,
// grabbing data and adding records
var line = ts.readLine();
// Check date email sent
idx = line.indexOf("Date:");
if (idx == 0) {
stat_date = Date.parse(line.slice(6, 40));
}
// Check for fans
idx = line.indexOf("ans this week");
if ( idx >= 0) {
new_fans = line.slice(0, idx-2);
total_fans = line.slice(line.indexOf("(") + 1,
line.indexOf("total") - 1);
}
// Check for wall posts
idx = line.indexOf("all posts");
if (idx >= 0) {
new_posts = line.slice(0, idx-2) + 0;
}
// Check for visits
idx = line.indexOf("isits to your");
if (idx >= 0) {
visits = line.slice(0,idx-2);
// Should have all the data now so insert a record
stat_date = new Date(stat_date);
var short_date = stat_date.getFullYear() + "-"
+ pad(stat_date.getMonth() + 1, 2) + "-"
+ pad(stat_date.getDate(), 2);
if (!conn.insertRecord(table, [++i,
short_date,
new_fans,
new_posts,
visits,
total_fans])) {
var msg = "Cannot insert into " + table.caption() + '\n';
msg += "Date: " + stat_date.toDateString()
+ " " + short_date + '\n';
msg += "New Fans: " + new_fans + '\n';
msg += "Total Fans: " + total_fans + '\n';
msg += "New Posts: " + new_posts + '\n';
msg += "Visits: " + visits;
QMessageBox.information(0,"Error", msg);
}
}
}
QMessageBox.information(0, "Records Added:", i);
}
statsFile.close();
function pad(number, length) {
var str = '' + number;
while (str.length < length) {
str = '0' + str;
}
return str;
}
A possible bug in the script shown in Listing 1 is that it assumes there are no current records in the table, and it creates primary keys starting at 1. It is okay to run the script once, but if it is run again, it tries to overwrite records that have an ID matching what it is trying to insert. To make it more robust, it first needs to find out the current maximum of the ID field (this would be a good exercise to get used to writing scripts).
When executed from the script toolbar, the script gathered 11 records worth of data, which is visible from the Table Data View (Figure 3).
It's worth pointing out that the above script took a lot of trial and error, as it is not initially obvious that it is possible to import extra libraries or use Kexi-specific functions. The documentation needs work to make this easier for new users, and submissions are very welcome at the KDE Userbase Web site.
At the moment, the data is ordered in the order in which it was extracted from KMail. Because I need it to be in ascending date order, I created a query to sort it. From the Create tab, this time I chose Query. I wanted all fields except the auto-incrementing primary key, so I set it up as shown in Figure 4.
Switching to Data View executes the query and displays the results (Figure 5).
I saved the query as qryStats for use in a report.
A new feature of Kexi 2 is the report plugin. This allows reports to be designed and executed directly within Kexi using a GUI editor similar to report designers in other database systems, such as Microsoft Access, Crystal Reports or Oracle Reports. In Kexi 1.6, reports were available as a separate add-on from kde-apps.org, but it did not contain as many features as the version in Kexi 2, and it was not fully integrated with the application, as the designer was an external program.
Reports can be printed, saved as a PDF, exported to HTML or OpenDocument Spreadsheet files or simply remain in the database for live viewing. It is possible to save the report in all these formats because of the two-stage generation process. Reports first are rendered into an intermediate description, and this description is used to generate the final version in whatever format is selected. In a future version, it is likely that extra formats will be supported, such as OpenDocument Text and XML, suitable for further processing using XSLT.
From the Create tab, I choose Report to create a blank report with a single “Detail” section. The structure of a report is based around Sections, which can be page headers or footers, report header or footer, or Group sections where data is grouped on a field value.
Initially, all I want is a simple tabular view of the data, so all the fields will go into the detail section, apart from a header, and the field titles, which must go either in a Page Header or Report Header. From the Section Editor on the report toolbar, I added a Report Header, and using the Report Design tab on the menu bar, I added fields and labels to create the report layout. From the Data Source tab on the sidebar, I set the reports data source to the qryStats query I created above. Finally, I set the Control Source property of each field item to the corresponding field in the query and the Caption of the labels appropriately. In the end, it looked like Figure 6, and it generated a report, shown in Figure 7.
This gets the job done, but it isn't quite as “jazzed up” as I would like. It's common in desktop applications to alternate the background color of rows to make it more obvious where each set of data begins and ends, so let's try that.
I created another script, but this time set its type to Object, as it is to be associated with the report object. Report scripts are event-driven—that is, whenever a certain event occurs in the generation of the report, the associated code in the script is called. Report scripts use the features of Kross::Object, where each object in a report can be associated with a script object, making it more object-oriented in nature. Each script object can have its own variables and functions. Report objects can be the report itself or any of the report sections. To make it more clear, the final script looks like what's shown in Figure 8.
This is quite a simple script. There is an object called detail, containing a function OnRender, which will be called whenever a detail section is rendered. The function keeps track of how many times it has been called and alternates the background color. The final line of the script associates the detail function with the detail section of the report.
Then, in the report, I set the Interpreter Type to QTScript and the Object Script property to the name of the script. It is important that the Interpreter type of both the report and script match; otherwise, the script won't be presented as an option in the Object Script list.
The generated report now looks like Figure 9.
It's not so great with the white background on the fields, so I went back to the designer and changed the Opacity property of each of the fields to 0 to make them transparent, resulting in a more reasonable report (Figure 10).
Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
| Trying to Tame the Tablet | May 08, 2013 |
| Dart: a New Web Programming Experience | May 07, 2013 |
- RSS Feeds
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Home, My Backup Data Center
- A Topic for Discussion - Open Source Feature-Richness?
- What's the tweeting protocol?
- Dart: a New Web Programming Experience
- Developer Poll
- May 2013 Issue of Linux Journal: Raspberry Pi












1 hour 10 min ago
3 hours 42 min ago
4 hours 59 min ago
5 hours 34 min ago
5 hours 57 min ago
10 hours 45 min ago
11 hours 32 min ago
13 hours 6 min ago
14 hours 43 min ago
16 hours 40 min ago