Sunday, September 30, 2012

Chrome Web Store: new way to publish Google Apps Script


Apps Script developers that wished to share their work with a larger audience have traditionally turned to the Script Gallery, which allows other users to copy and install the script into their own spreadsheets. While appropriate for custom functions and spreadsheet extensions, it didn't fit well when distributing more complex functionality and apps.

In this blog post we'll be highlighting a newer way to distribute your scripts: deploying them as a web app and publishing them to the Chrome Web Store. Compared to the Script Gallery, the Chrome Web Store has some distinct advantages for developers:

  • Automatic updates - Change your code, do some testing, and publish a new version to update the app for all users instantly.
  • More information - Detailed descriptions, promotional images, ratings, and reviews lead tocompelling listings.
  • Greater discoverability - Visit the Chrome Web Store site to learn about the benefits.

Looking through the Script Gallery we believe there are many scripts that would be a great fit for the Chrome Web Store and would benefit from the advantages listed above. Some aspects of a good candidate script are:

  • Custom UI - Users interact with your script through a custom user interface, not via custom spreadsheet functions or onEdit triggers.
  • Background processing - Your script uses time-based triggers to do work in the background and doesn't require that the Google Spreadsheet is open.
  • Not primarily about Google Spreadsheets - Your script's main focus isn't spreadsheets and you utilize a variety of services to provide separate functionality.

A great example of such a script is Gmail Meter, which was first launched in the Script Gallery but has since been published to Chrome Web Store. Now users can install and run the script without needing to create a spreadsheet, see script code, or set up triggers. It may take a little work to update a spreadsheet-based script to use the web app model, and some common tasks are:

  • Implement doGet() - Instead of showing your custom UI on the spreadsheet with Spreadsheet.show(), put the same code into the doGet() method and return the finalUiInstance or HtmlOutput object.
  • Deploy as a web app - Configure your script to run as a web app, which will assign it a unique URL. In most cases you'll want the web app to run as the user so that it can access their services.
  • Remove references to active spreadsheet - When published as a web app there is no active spreadsheet, so if your script needs access to a spreadsheet then you'll need to use SpreadsheetApp.openById() instead. You can use the DocsList service or theDocsListDialog UI widget to help users locate the desired spreadsheet.
  • Handle multiple users - When published as a web app users access the same copy of the script, so you may need to change the way you organize data to avoid conflicts.UserProperties work well for small settings, and when using ScriptDb make the user's login ID or email address part of the objects so that you can filter for them later.

Publishing to the Chrome Web Store only takes a few clicks, and we provide instructions for the process in our documentation. We hope that you are inspired to take your scripts to the next level, and if you have any questions along the way feel free to reach out to us on StackOverflow or Google+.

By Eric Koleda
Ref: http://googleappsdeveloper.blogspot.com/2012/09/expand-your-reach-with-web-apps.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+GoogleAppsDeveloperBlog+%28Google+Apps+Developer+Blog%29

Wednesday, September 26, 2012

Auto refresh page with Javascript & Meta tag

1. Using meta tag, for example to auto refresh to your url every 1 second.
<meta http-equiv="refresh" content="1;url='http://your_url' " />

2. Using Javascript, for example to auto refresh to your url every 1 second:
<script>
  function auto_refresh() {
    window.location = 'http://your_url';
  }
  setTimeout(auto_refresh, 1000);
</script>


3. Using Javascript + jQuery to auto refresh when having no activity in some minutes (e.g. 1 minute)
<script>
     var time = new Date().getTime();
     $(document.body).bind("mousemove keypress", function(e) {
         time = new Date().getTime();
     });

     function auto_refresh() {
         if(new Date().getTime() - time >= 60000)
             window.location.reload(true);
         else
             setTimeout(auto_refresh, 10000);
     }

     setTimeout(auto_refresh, 10000);
</script>


Monday, September 24, 2012

IIS 7: set maxLogFileSizeKB

When the log size comes over maxLogFileSizeKB, you will get LOG_FILE_MAX_SIZE_TRUNCATE event in the log file. To change maxLogFileSizeKB to 1024 KB (default is 512 KB), run on shell (cmd):


cd /d  %windir%\system32\inetsrv
appcmd set config /section:sites -siteDefaults.traceFailedRequestsLogging.maxLogFileSizeKB:1024

Friday, September 21, 2012

MS SQL Server Management Studio 2008: edit table data


1. Right-Click table and select "Edit Top 200 Rows"
2. Right-Click anywhere on the results, navigate to Pane -> SQL

==> Change the SELECT statement there, e.g. adding a WHERE clause at the bottom.

Windows Server 2008: Add IIS6 Compatibility

Do you need IIS Compatibility to run your old apps, just do as the following:

Server Manager >> Roles >> Web Server (IIS ) >> right click >> Add Role Service >> select IIS6 Management Compatibility >> Next >> Install

Wednesday, September 19, 2012

MS SQL 2008 R2: Export table data to SQL file

1. Right click on the DB
2. Select Task >> Generate Scripts
3. In Choose Object section, select specific database objects
4. Select your tables
5. Next, in Set Scripting Options, click Advanced button >> Types of data to script >> select Data only

Hint:
For old versions of MS SQL, using Sql Server Management Studio 2008 R2 to connect & export data

MS SQL: empty data of all tables

Sometimes you need to empty data of all tables in a database, what you should do:

1. Backup your DB, and run the following command to see disabled triggers:
SELECT
    sysobjects.name AS trigger_name
    ,USER_NAME(sysobjects.uid) AS trigger_owner
    ,s.name AS table_schema
    ,OBJECT_NAME(parent_obj) AS table_name
    ,OBJECTPROPERTY( id, 'ExecIsUpdateTrigger') AS isupdate
    ,OBJECTPROPERTY( id, 'ExecIsDeleteTrigger') AS isdelete
    ,OBJECTPROPERTY( id, 'ExecIsInsertTrigger') AS isinsert
    ,OBJECTPROPERTY( id, 'ExecIsAfterTrigger') AS isafter
    ,OBJECTPROPERTY( id, 'ExecIsInsteadOfTrigger') AS isinsteadof
    ,OBJECTPROPERTY(id, 'ExecIsTriggerDisabled') AS [disabled]
FROM sysobjects

INNER JOIN sysusers
    ON sysobjects.uid = sysusers.uid

INNER JOIN sys.tables t
    ON sysobjects.parent_obj = t.object_id

INNER JOIN sys.schemas s
    ON t.schema_id = s.schema_id

WHERE sysobjects.type = 'TR' and OBJECTPROPERTY(id, 'ExecIsTriggerDisabled') = 1
order by table_name


2. Create a store procedure, e.g. emptyAllTables with code as the following:

CREATE PROCEDURE emplyAllTables
AS

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'

GO

In the case of you want to skips some important tables and reset identity of table, you can use the following SP:


CREATE PROCEDURE emplyAllTables (@ResetIdentity bit)
AS

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'


DECLARE @SkipTables nvarchar(max)
DECLARE @TableName varchar(255)
DECLARE @SQL varchar(255)
SET @SkipTables = 'table1,table2,table3'

DECLARE curTable CURSOR LOCAL FOR
SELECT Table_Name FROM INFORMATION_SCHEMA.TABLES WHERE CHARINDEX(Table_Name,@SkipTables) = 0 AND TABLE_TYPE='BASE TABLE'

OPEN curTable
FETCH Next FROM curTable INTO @TableName
WHILE @@FETCH_STATUS=0
BEGIN
SET @SQL = 'DELETE FROM ' + @TableName

IF @ResetIdentity = 1 AND OBJECTPROPERTY (OBJECT_ID(@TableName),'TableHasIdentity') = 1
SET @SQL = @SQL + '; DBCC CHECKIDENT(''' + @TableName + ''',RESEED,0)'

EXECUTE(@SQL)
--PRINT @SQL

FETCH Next FROM curTable INTO @TableName
END


EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'

GO

3. Manually disable triggers in step 1

Now you have an empty DB for your new start up :)

Saturday, September 15, 2012

MySQL: Check logs of queries

Apply for MySQL >= 5.1.12:
1. Open MySQL console
2. Execute SET GLOBAL log_output = 'TABLE';
3. Execute SET GLOBAL general_log = 'ON';
4. Check table mysql.general_log (should ORDER BY event_time DESC)

To turn off:
5. Execute SET GLOBAL general_log = 'OFF';

If you want to put logs to file:
SET GLOBAL log_output = "FILE";
SET GLOBAL general_log_file = "your_folder/your_file.log"

Thursday, September 13, 2012

Joomla 2.5: Where Does JToolBarHelper::custom Load Icon?

It's loaded from: administrator/templates/<selected template>/images/toolbar

For example: create a NewButton on the toolbar of your component
1. Copy ButtonIcon into administrator/templates/<selected template>/images/toolbar floder
2. Add new line to administrator/templates/<selected template>/css/template.css
.icon-32-ButtonIcon { background-image: url(../images/toolbar/icon-32-ButtonIcon.png); }
3. Declare it in your code:
JToolBarHelper::custom( 'yourtask', 'ButtonIcon.png', ' ButtonIcon .png', 'Button Name', false,  false );

Wednesday, September 12, 2012

Best free web hosting services



Free Web Hosting
Services

Disk
Space
Monthly
Bandwidth
MySQL
Databases
FTP
Support
Uploaded File
Restrictions
Forced
Ads
Xtreemhost
2500 MB
100 GB
10
yes
4 MB
no
Frihost
1500 MB
35 GB
unlimited
yes
unlimited
no
000webhost
1536 MB
100 GB
2
yes
5 MB
no
Byethost
unlimited
unlimited
unlimited
yes
4 MB
no
Podserver
300 MB
10 GB
7
yes
5 MB
yes
Freehostia
250 MB
6 GB
1
yes
500 KB
no
Zymic
6000 MB
50 GB
3
yes
15 MB
no
Uhostfull
unlimited
unlimited
unlimited
yes
unlimited
no
Beesimple
1024 MB
10 GB
10
yes
2 MB
no                                         
Subscribe to RSS Feed Follow me on Twitter!