How to convert txt file to html using perl - perl

I have run some scripts to generate storage capacity report and configuration settings report using perl. I would like send this report to my mail id in html using perl.
Please note that I am new to perl programming.

Your question is very vague, so it's hard to be of much help. This might point you in the right direction though.
You basically have three tasks here.
Parse your report into data structures.
Use your data structures to generate an HTML document.
Send the HTML document by email.
I can't really help with step 1 as I know nothing about your report. If you have your file in CSV format, then Text:CSV will be useful to you. It's worth pointing out that if you're generating this report, then you could generate it in a format that is easier to parse - JSON, for example.
For step 2, I'd recommend a templating engine. I'd use the Template Toolkit, but other options are available. The idea is that you create a template file that contains all of your HTML with "tags" where you want your variable data to go. On a simple level it might look something like this:
<html>
<head><title>Some Title</title></head>
<body>
<h1>Some Title</h1>
<p>Blah...</p>
<table>
[% FOREACH row IN data -%]
<tr><td>[% row.value %]</td><td>[% row.another_value %]</td></tr>
[% END -%]
<table>
</body>
</html>
Assuming that's in a file called email.tt and you have your data in an array of hashes called #data, then you'd process the template like this:
use Template;
#data = ({
value => 'something',
another_value => 'something else',
}, {
value => 'something',
another_value => 'something else',
});
my $tt = Template->new;
$tt->process('email.tt', { data => \#data }, \$email_body)
or die $tt->error;
That will give you your expanded HTML in $email_body. And that brings us to step 3.
I recommend Email::Stuffer for sending email.
use Email::Stuffer;
Email::Stuffer->from ('you#example.com')
->to ('someone_else#example.com')
->html_body($email_body)
->send;

Related

SugarCRM - Custom Print Layout

I created a model in SugarCRM and I need to print the details view. But this must be printed with a different layout.
It must have the company logo for example, if I just wanted do print the bean information, the default print would be sufficient, but I need something closer to a report, because this info will be given to the costumer.
I would like to know if there is a way to create a printing template, and if there is, how can I create one?
Thanks for your help, if you need more information please comment.
rfnpinto
Even in SugarCRM CE you can leverage the included Sugarpdf class, which is an extension of TCPDF.
If you have SugarCRM Professional you can find examples of this in the Quotes module. If not, you're flying blind, so I can give you the gist of it.
Using the Contacts module as an example, create /custom/modules/Contacts/views/view.sugarpdf.php with contents like the following:
<?php
require_once('include/MVC/View/views/view.sugarpdf.php');
/**
* this defines the view that will drive which PDF Template we use
*/
class CustomContactsViewSugarpdf extends ViewSugarpdf{
public function display(){
$this->sugarpdfBean->process();
$this->sugarpdfBean->Output($this->sugarpdfBean->fileName,'D');
sugar_die('');
}
}
Create /custom/modules/Contacts/sugarpdf/sugarpdf.pdfout.php with contents like the following:
$contact = BeanFactory::getBean($_REQUEST['record_id']);
if(empty($contact->id)){
sugar_die('Could not load contact record');
}
$name_str = "<p><strong>Name: {$contact->name}</strong></p>";
$this->writeHTML($name_str);
$this->drawLine();
}
function buildFileName(){
$this->fileName = 'ContactPDFOut.pdf';
}
}
From there, you can print a PDF document per your format if you hit the URI index.php?module=Contacts&action=sugarpdf&sugarpdf=pdfout&record_id=1234
Once that's working in the way you want, you can add a button the Contacts Detailview to access that URI more easily. Dig into /custom/modules/Contacts/metadata/detailviewdefs.php and find the existing buttons array. It'll look something like this:
'buttons'=>array('EDIT', 'DUPLICATE', 'DELETE', 'FIND_DUPLICATES'
Just enhance this with your own button and hidden input
'buttons'=>array('EDIT', 'DUPLICATE', 'DELETE', 'FIND_DUPLICATES',array(
'sugar_html'=>array(
'type' => 'submit',
'value' => '(Wrongfully Hardcoded Label) Print PDf',
'htmlOptions'=>array(onclick => 'this.form.action.value=\'sugarpdf\';this.form.sugarpdf.value=\'pdfout\'')
)
)
...
The hidden array should be part of $viewdefs['Meetings']['DetailView']['templateMeta']['form'] and defined like so:
'hidden' => array('<input type="hidden" name="sugarpdf">'),
I haven't tested this recently but this is the general idea of adding custom Print PDF abilities to any particular screen within SugarCRM. TCPDF options are pretty extensive and forming the template just right is going to be very tedious, but I think once the "plumbing" is working here you'll figure that bit out, but feel free to ask followup questions.

Strategy for migrating Perl CGI to Template Toolkit?

I have a relatively large legacy Perl/CGI/DBI web application which generates HTML on-the-fly piece by piece. We are reworking the HTML being produced, to come in to compliance with HTML 5 / CSS 3. This would be a good time to move to some sort of template system. We do NOT want to engage in a complete rewrite, and thus do NOT want to migrate to a framework such as Catalyst.
I'm thinking that Perl Template Toolkit might be our lowest-impact means. I'm re-reading the venerable Badger Book to study up on feasibility.
My question is this. Has anyone here migrated "old school" Perl web code to Template Toolkit? Are there any tricks you can share for minimizing the rewrite/rework needed? We have not 100% decided on Template Toolkit, either. If there is an alternative which we should consider?
What problem, specifically, are we trying to solve? We're generating invalid HTML and need to clean that up. Since we're cleaning, we want to produce fully-valid HTML 5 and, to the extent practicable, valid CSS3 and Javascript. We use jQuery, jQuery UI widgets, and AJAX via jQuery. We have typical Page Controller MVC architecture except no View layer as such. We'd like to go to some sort of template system but don't want to rewrite everything (or much of anything!) to migrate.
Thank You!
Ed Barnard, Cannon Falls MN
Here's what I've found, as I've moved my practice from CGI.pm to TT, and what I've also learned along the way using HTML::Mason, HTML::Template, Text::Template, and working with ERB and HAML in Rails.
The more logic you have in in your displays, especially if it is written in a display specific language, the less fun you're going to have.
I've come to prefer HAML for the reduction in size of the contents of my templates [ In HAML, closing tags are implied by indentation ]
Perform as much of the logic to compute the various dynamic bits of the page before you drop into the template, in the application's native language. [ call view methods, before engaging in rendering ].
In relation to (3), by using methods, instead of inline display/rendering logic, you can make your templates declarative, so while you might be performing logic in the middle of the render, your templates don't have a bunch of IF/THEN/ELSE logic causing clutter.
Let's imagine a reasonably small, contrived web page made up of a header, and footer and a body. Let's assume that the footer is completely static, the body changes every time a new page loads, but the header only changes when a user logs in/out.
You can imagine the header containing code like this:
<header>
[% IF $user.is_logged_in THEN %]
Hello [% $user.name %] - Log Out
[% ELSE %]
Please Log In
[% END %]
</header>
But you're better off in the long term doing this in header.tt:
<header>
[% user_info($user) |html %]
</header>
and this in View::Helpers::Header.pm:
sub user_info {
my $user = shift;
if ($user->{is_logged_in} ) {
return "Hello $user->{name} - " . logout_link($user->{id});
}
else {
return "Please " . login_link();
}
}
sub logout_link {
my $userid = shift;
return qq(Log Out)
}
You can, of course, implement the view helpers in TT rather than pure Perl, and I don't have any kind of numbers for you, but if you've done all of your logic in Perl already, you can refactor the Perl into modules (if it isn't there already), instead of re-coding them in TT.
As part of your test suite, consider an HTML validator like HTML::Lint or HTML::Tidy.

Call to Subroutine from Catalyst Controller

I am working on catalyst to design a front end for a database. I am new to perl and catalyst. I am stuck with one error in the controller.
I want to fetch gene names from one table and pass each gene name to a subroutine gene_name(call a subroutine gene_name) which will perform certain function. I some how fetched the column with gene names but they are in the form of Hash reference to other table. My call to gene_name is not working.
Any idea how to pass the values to the subroutine rather than reference?
My code is as follows:
my #gene_list = $c->model('Gene::GeneTable')->search({
},{
column =>[qw/symbol/],
}
);
foreach my $gene (#gene_list){
push #gene_aliases, &gene_name($gene);
}
The error I am getting after executing the code is as follows:
DBIx::Class::ResultSet::find(): Can't bind a reference (MyApp::Model::Gene::GeneTable=HASH(0x7ff6d88b7c58))
UPDATED
My gene_name() subroutine is in another module which I have included in the controller. Now I have changed the for loop(in controller) as following and currently it is passing gene name to gene_name() to fetch aliases(But query remains the same):
foreach my $gene (#gene_list){
push #gene_aliases, &gene_name($gene-> symbol);
}
I am accessing the #gene_aliases in my view file as follows:
[% FOREACH g in gene_aliases -%]
[% g %]
[% END -%]
The above code is fetching hash references instead of names in the page. I am not able to display the gene names on web page.If I give [% g.symbol %] in for loop then the page would be empty with no error message.Hope this would be sufficient information for answering my question. If not I would elaborate on it.
My SQL query is as follows:
Select Symbol from GeneTable;
Thanks in advance
UPDATED2
As I am not a full time programmer, I am asking these questions on the blog. Kindly help me resolve my issues. If in case I have search form which takes gene name from user and this gene name has to be passed to the gene_name() subroutine, how do I pass this (to the controller and how to call the gene_name()). Kindly help me in resolving this issue.
My form in view.tt is as follows:
<form method="post" action "[% c.uri_for('/gene')%]">
<input type="text" name="search_alias">
<input type="submit" name="alias_search" value="Search">
</form>
All my aliases are in the other table called Alias, which is been used in gene_name() subroutine.
Either the gene_name() function needs to expect a GeneTable object being passed to it, or you would call it like this: gene_name($gene->symbol).
Having said that, the Controller does not look like the right place for this, based on what limited information you've provided.
It would make a lot more sense to have gene_name as a method of Gene::GeneTable itself, ie:
package GeneTable;
...
sub gene_name {
my $self = shift;
my $gene_name = ... # do something with $self->symbol
$gene_name
}
...
So that the ->gene_name method is available to any GeneTable object in any context.
UPDATE following OP's initial two comments
It sounds like gene_name() (which possibly should be called gene_aliases()) is a method of a Gene object. Putting such a conversion into a Controller does not adhere to good MVC philosophy.
Presumably you have model code somewhere - MyApp/Model/Gene/ most likely - and this sub should exist inside Gene/GeneTable.pm. Then you could use it thus:
[%- FOREACH g IN gene_list -%]
[% g.symbol %]<br/><ul>
[%- FOREACH gn IN g.gene_name -%]
<li>[% gn %]</li>
[%- END -%]
</ul>
[%- END -%]
in your template, and anywhere else you have a GeneTable object or collection thereof.
UPDATE #2 Following updated question
DBIx:Class will return an array of objects when called in list context as you do. Perhaps you need to add some Data::Dumper->Dumper() calls to get a handle on what each step is returning to you.
I suggest you add the following line immediately after your call to ->search():
$c->log->debug("gene_list contains: ", Data::Dumper->Dumper(\#gene_list));
...and possibly the equivalent debug for #gene_aliases after you've populated that.
That might give you a clearer picture of what you're getting back from your search, but I'd hazard a guess you're getting Gene::GeneTable objects.

Find and replace variable div contents

I have a php page which contains a large amount of HTML in it. One part of the HTML has a div in the following format:
<div class="reusable-block" id="xyzabcwy">there is a lot of HTML here which may be in any format</div>
Keep in mind, this div is contained within the DOM at any location however, I do know the div ID programatically.
I was originally finding this string within my database, since a record of it exists there however, the format between the data in the database record and the page are sometimes different due to whitespace but other than the white space, the strings are exactly the same. The problem is, I don't know what format the whitespace is in.
It seems it is better to write a regular expression to find this div and replace it entirely.
I could use a hand though.
Other ideas are also welcome.
Many thanks!
If you are using jQuery,
$('#xyzabcwy').html(new_data);
if not
document.getElementById('xyzabcwy').innerHTML = new_data;
otherwise, here is a PHP example.
Edit: PHP
<?php
$id = "xyzabcwy";
$html = "<div id=\"" . $id . "\">this is html</div>";
$newdata = "test";
echo preg_replace("#<div[^>]*id=\"{$id}\".*?</div>#si",$newdata,$html);
?>
 This should output
<div id="123">test</div>
Answer from: Replace a div content with PHP

Why can't WWW::Mechanize find the right form?

I'm using WWW::Mechanize to retrieve a form from a webpage:
#!/usr/bin/perl
use WWW::Mechanize;
my $mechanize = WWW::Mechanize->new();
$mechanize->proxy(['http', 'ftp'], 'http://proxy/');
$mechanize->get("http://www.temp.com/");
$mechanize->form_id('signin');
The website HTML has code as follows
<form action="https://www.temp.com/session" id="signin" method="post">
but I get the error
There is no form with ID "signin" at SiteScraper.pl
What do I do?
Without knowing exactly could be wrong, you might try to output whatever forms that WWW::Mechanize is able to find in the response by using:
use Data::Dumper;
print Dumper($mechanize->forms());
It should output all the forms and their respective attributes etc.
Double check that the form is in the dump, otherwise something is wrong. Then check that the form's ->{attr}->{id} is what you expect as well.
You can also try to select the form using another way, e.g. by name, and see if that helps.