Archive for the ‘Scripting&Automation’ Category
Auto beautifying C++ code
Disini saya ingin share simple script untuk “mempercantik” c++ code disuatu folder project dan melakukan svn commit setelah itu. jadi semacam selalu ada auto corrector jika kamu menulis code yang tidak sesuai aturan ( bahkan mungkin aturan yang kamu buat sendiri) .
code yang rapih diharapkan memiliki sedikit bugs dan juga ingat programmer menulis code tidak hanya untuk mesin, tetapi juga untuk dibaca manusia yang lain. untung nya untuk masalah indentation & formating ada software keren & free untuk melakukan ini, yaitu AStyle ( http://astyle.sourceforge.net/ ) . dengan batch script dibawah ini, semuanya terjadi otomatis :
@echo off SET ASTYLE_DIR="N:\test\AStyle\bin" SET SRC_ROOT_DIR="N:\test\test_astyle\source01" echo ..AStyle beautfying... %ASTYLE_DIR%\AStyle.exe --style=google --indent=spaces=4 -xn -xc -xl -xk -xe -n --align-pointer=type --recursive %SRC_ROOT_DIR%\*.h %SRC_ROOT_DIR%\*.cpp %SRC_ROOT_DIR%\*.hpp %SRC_ROOT_DIR%\*.c echo ..done.. echo ..SVN Comitting.. svn commit %SRC_ROOT_DIR% --message "auto commit: Astyle auto beautify code " echo ..done..
SET ASTYLE_DIR : dir dari astyle exe
SET SRC_ROOT_DIR : root dir source code
dengan menambahkan ini scheduler task / script semuanya berjalan otomatis .
// edie // surabaya 23-12-2013
File mana yang termodifikasi ?
Misalnya saya memiliki 1000 file yang akan saya prosess oleh suatu program, dengan script saya bisa melakukannya seperti ini :
for i=0 to i=1000 { process file ke-i }
jadi dengan klik sebuat script pekerjaan selesai. Namun, ada beberapa file dari 1000 file tersebut yang berubah / saya modifikasi lagi, sehingga saya perlu mengulang eksekusi script diatas lagi :
for i=0 to i=1000 { process file ke-i }
Ini tentu tidak efisien dan lama, karena saya mengubah beberapa file, namun 1000 file masih diprocess lagi. Kode yang efisien seharusnya begini :
for i=0 to i=1000 { jika file ke-i ter-modifikasi, maka process file ke-i }
untuk itu saya perlu suatu program untuk mengecek apakah file ke-i, termodifikasi / tidak. Pekerjaan semacam ini bisa mungkin saja dilakukan dengan python, lua, atau scripting language yang lain. Namun kali ini , (dan waktu2yg lain) , saya suka pakai c/c++ dengan kombinasi Batch , hehehe. Dan, program super simple itu sudah jadi, xediff.exe :d . berikut contoh efisien script yang saya maksud .
[ run_works.bat ]
@echo off SET XDIFF=N:\XediProjects\Release\Xediff.exe SET TARGETDIR=D:\test\test for %%i in ( %TARGETDIR%\*.* ) do ( call checkmodified.bat %%i ) echo .. Done..
[ checkmodified.bat ]
@echo off %XDIFF% %1 > temp.txt set /p XDF= < temp.txt if "%XDF%"=="1" ( @echo ..do something: this file changed %1 %XDF% ) del temp.txt
Terdapat 2 file batch, run_works.bat yang memanggil checkmodified.bat. Alasan kenapa jadi 2 file BAT adalah : pipe di BAT tidak bisa bekerja. { apa itu pipe? } . lalu apa yang dilakukan xediff.exe? : xediff.exe menerima argumen berupa file path , dan memberikan output (stdout) ‘1’ & ‘0’ ,file termodifikasi atau tidak . xediff.exe adalah program simple yang mengecek last written time dari suatu file . berikut kodenya [ this is ugly, but i like to share 🙂 ]
[xediff.exe]
// Xedi Xermawan <c> 2013
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <fstream>
using namespace std;
bool GetLastWriteTime(HANDLE hFile, SYSTEMTIME& lastaccess,TCHAR* fileLastAccess) {
bool isEqual = true;
FILETIME ftCreate, ftAccess, ftWrite;
SYSTEMTIME stUTC, stLocal;
// Retrieve the file times for the file.
if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite))
return false;
// Convert the last-write time to local time.
FileTimeToSystemTime(&ftWrite, &stUTC);
SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
if(stLocal.wMonth != lastaccess.wMonth ||
stLocal.wDay!= lastaccess.wDay ||
stLocal.wYear!= lastaccess.wYear ||
stLocal.wHour!= lastaccess.wHour ||
stLocal.wMinute!= lastaccess.wMinute ||
stLocal.wSecond!= lastaccess.wSecond
)
{
isEqual = false;
}
fstream fileOut(fileLastAccess,std::ios::out|std::ios::binary);
const char* c=reinterpret_cast<const char*>(&stLocal);
fileOut.write(c,sizeof(stLocal));
fileOut.close();
return isEqual;
}
bool GetLastTimeAccess(SYSTEMTIME& ret, TCHAR* fileLastAccess) {
fstream fileIn(fileLastAccess,std::ios::in | std::ios::binary);
if(!fileIn) {
return false;
}
fileIn.read( reinterpret_cast<char*>(&ret), sizeof(ret) );
fileIn.close();
return true;
}
void BreakPath(TCHAR* filepath, TCHAR* filedir, TCHAR* filename) {
unsigned int i=0,lastSlash=0;
TCHAR buff[MAX_PATH];
while(*filepath !='') {
buff[i] = *filepath;
if(*filepath++=='\\')
lastSlash=i;
i++;
}
buff[i]='\0';
i=0;
while(i < lastSlash+1) {
*filedir++ = buff[i++];
}
*filedir++ ='.';
*filedir++ ='x';
*filedir++ ='d';
*filedir++ ='f';
*filedir++ ='\\';
*filedir='';
while(buff[i] !='') {
*filename++ = buff[i++];
}
*filename ='\0';
}
void FixPath(TCHAR* filedir, TCHAR* filename,TCHAR* filenamefix) {
while(*filedir !='') {
*filenamefix++ = *filedir++;
}
while(*filename !='') {
*filenamefix++ = *filename++;
}
*filenamefix++='.';
*filenamefix++='x';
*filenamefix++='d';
*filenamefix++='i';
*filenamefix++='f';
*filenamefix++='f';
*filenamefix='\0';
}
int _tmain(int argc, TCHAR *argv[]) {
HANDLE hFile;
int retVal = 1;
if( argc != 2 ) {
retVal = 1;
printf("%d",retVal);
return retVal;
}
TCHAR* filepath = argv[1];
TCHAR filedir[MAX_PATH];
TCHAR filename[MAX_PATH];
TCHAR filename_fix[MAX_PATH];
SYSTEMTIME lastaccessnoted;
BreakPath(filepath,filedir,filename);
CreateDirectory( filedir , NULL );
FixPath(filedir,filename,filename_fix);
GetLastTimeAccess(lastaccessnoted, filename_fix );
hFile = CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL,OPEN_EXISTING, 0, NULL);
if(hFile == INVALID_HANDLE_VALUE) {
retVal = 1;
printf("%d",retVal);
return retVal;;
}
if( (GetLastWriteTime( hFile, lastaccessnoted, filename_fix ) )) {
retVal = 0; // file same // not modified
printf("%d",retVal);
return retVal;;
}
CloseHandle(hFile);
printf("%d",retVal);
return retVal;
}
// edi ermawan // yogjakarta 27042013
// keywords: file modified check, c++, c, Batch, incremental build
Otomatisasi dengan script : windows powershell
Kita mungkin pernah menjumpai orang-orang yang bekerja sangat cepat atau menyelesaikan banyak pekerjaan dengan waktu yang singkat, dan ada yang biasa saja dan bahkan mungkin lambat. Kenapa? Jawabannya mungkin : “orang kan beda-beda”, maksudnya? : “ada orang pintar dan ada orang bodoh”. :d, just kiddin’ . Yah, itu tentu tidak benar . Mungkin ada orang yang diberi kemampuan mengatur waktunya dengan baik & memiliki fokus yang tinggi dalam bekerja ( say NO to distraction ). Dan mungkin dia menggunakan “alat” yang benar dan cocok dalam menyelesaikan pekerjaan. Dan mungkin juga mereka menggunakan “magic” :-p, maksudku mereka mengotomatisasi pekerjaan. Kalau kita bekerja dengan komputer, banyak hal yang bisa di-otomatisasi.
Kita harus ingat, komputer dibuat dengan kelebihan antara lain: komputer bekerja sangat cepat dan dapat menyelesesaikan pekerjaan yang sama yang berulang-ulang. Dan tentu, tanpa rasa bosan 😀 . Jadi jika kita mengerjakan pekerjaan yang sama dan berulang-ulang DI komputer, maka kemungkinan, kita masih belum bisa memaksimalkan fungsi komputer. Pekerjaan sebanyak mungkin harus bisa diotomatisasi. Bagaimana caranya? Banyak cara, namun saya lebih spesifik di blog post ini: menggunakan computer shell script/computer script/script. Script, sebuah source code yang bisa dijalankan tanpa harus dikompilasi dan di-linking, salah satu tools yang sangat membantu untuk mengotomatisasi pekerjaan. Terdapat banyak script yang bisa dipilih : python, lua, VBScript, DOS Batch, Bash, windows powershell , dll .
DOS Batch merupakan scripting pertama yang saya pelajari waktu belajar komputer di SMU dulu, dan juga belajar lagi waktu bekerja, karena Batch digunakan untuk membuat MAKE file. Batch bisa menyelesaikan banyak hal , namun Batch sangat prone-error . Selain Batch tidak ada lagi scripting yang saya pelajari . Python sempat menarik perhatian, namun belum mencobanya. Minggu lalu, saya menemukan kata “Windows Powershell” di sebuah buku, dan saya langsung tertarik untuk mempelajarinya. Mungkin karena “Power” disitu, sepertinya cool 😀 . kalau kita membaca di Wiki, sepertinya memang benar-benar cool. Ok, saya mulai belajar, dengan motivasi “sepertinya cool” dan berharap bisa mengotomatisasi banyak pekerjaan dengan tool ini. Hehe . Windows Powershell di komputerku versi 3.0, dan ini versi terbaru. Untuk mendapat Windows Powershell prompt, cukup run Powershell.exe, misalnya saya run di directory N:\wpshell , command prompt sebagai berikut :
PS N:\wpshell>
seperti hal-nya scripting yang lain, kita bisa mengetik command langsung di command prompt atau menulis script di file lalu menjalankannya. Untuk menjalankan script , ada dua hal yang harus dilakukan , pertama men-settingexecution policy, karena nilai default-nya restricted, perlu di ubah sebagai berikut :
set-executionpolicy unrestricted
kedua, menjalankan script (misalnya script file diberi nama : testScript.ps1 ) sebagai berikut :
powershell -noexit “& “N:\wpshell\testScript.ps1”
Windows Powershell cukup mudah dipelajari, dan terdapat banyak resource di internet untuk mempelajarinya , seperti
http://get-powershell.com/?page=2
http://www.powershellmagazine.com
Sebagai latihan, saya mencoba mencari beberapa masalah untuk saya selesaikan. Berikut masalah dan solusi yang saya coba ( ya , ini memang simple, tapi saya senang men-share disini )
#Case 1 : Mengganti banyak nama file
saya memiliki banyak foto dari camera, nama filenya tidak terlalu informatif DSCN0001.JPG, DSCN0002.JPG, dst. Saya ingin menggantinya dengan misalnya: LiburanTahunBaru_001, LiburanTahunBaru_002, dst. yaitu dengan format LiburanTahunBaru_NNN.JPG, dimana NNN adalah nomor index. Berikut script yang saya buat :
#source folder
$sourceFolder ="N:\Foto_Nikon_camera\Tita"
#header
$newNameHeader="LiburanTahunBaru_"
$a = $(Get-Item $sourceFolder\*.*)
$index=0
foreach ($i in $a)
{
$newName =$newNameHeader + $index.ToString("000") + $i.Extension
Rename-Item $i $newName
$index += 1
}
#Case 2 : Mengelompokan file berdasarkan ekstensi
Internet browser ku adalah Google Chrome dan ketika saya mengunduh file, hasilnya ada di C:\Users\usenameku\Downloads, apapun jenis filenya semua masuk situ. Dan ketika folder tersebut mulai terisi banyak file dan daftar semakin memanjang, saya mulai memindah file berdasar file extension (.zip, .exe, .msi, etc. ) untuk mempermudah pencarian & kerapian. Saya lakukan secara manual. Poor habit. Dan yeah, ini bisa dilakukan secara otomatis dengan script :
#source folder
$sourceFolder ="C:\Users\usenameku\Downloads"
#header
$FolderHeader="\File"
#extension list
$extlist =@("zip", "rar","pdf","7z","jpg","png","exe","msi","mp3","wmv","mp4","flv","cpp","jar")
$index=0
#create folder if not exist
foreach ($i in $extlist)
{
$newName =$sourceFolder + $FolderHeader + "_" + $i
#check path existence
if(Test-Path $newName)
{
#folder is already exist, do nothing
}
else
{
New-Item $newName -Type directory
}
$index += 1
}
#get all items
$allitems = $(Get-Item $sourceFolder\*.*)
#move file to folder based on extension
foreach ($j in $extlist)
{
$newName =$sourceFolder + $FolderHeader + "_" + $j
foreach($k in $allitems)
{
if($k.Extension -eq ("."+$j))
{
if(Test-Path $k)
{
Move-Item $k $newName
}
}
}
}
#Case 3 : Mengunduh RSS
Banyak website yang menyediakan fitur RSS, salah satunya Yahoo. Beberapa link RSS Yahoo :
http://news.yahoo.com/rss/science
http://news.yahoo.com/rss/entertainment
http://news.yahoo.com/rss/health
http://news.yahoo.com/rss/sports
http://news.yahoo.com/rss/tech
http://news.yahoo.com/rss/bussiness
http://news.yahoo.com/rss/world
Dengan menggunakan link diatas kita bisa mendapatkan judul berita, link berita, dan isi berita, untuk pemrosesan lebih lanjut. Berikut script sederhana untuk mendapatkan judul dan link dari RSS :
$docxml = [xml] (New-Object System.Net.WebClient).Downloadstring($url)
$stitle = $docxml.rss.channel.item.title
$slink = $docxml.rss.channel.item.link
$sitems = $docxml.rss.channel.item
foreach($sitem in $sitems)
{
$sitem.title + " - " + $sitem.link >> link.txt
}
contoh hasil run :
Atom smasher hiatus sets stage for more discovery – http://news.yahoo.com/atom-smasher-hiatus-sets-stage-more-discovery-134311023.html
Spaceport wants protections from tourist lawsuits – http://news.yahoo.com/spaceport-wants-protections-tourist-lawsuits-213926570.html
#Case 4 : Mem-profil sebuah folder
Kadang saya ingin mengetahui apa yang membuat drive hardisk saya (misal drive D:\ ) penuh. Untuk mengeceknya saya perlu mengetahui folder dan file mana yang ukurannya besar ( memakan space ) . Jika info tersebut sudah didapat , maka bisa diambil keputusan: folder atau file apa yang bisa di pindah/ di hapus.
$startFolder = "G:\testScriptCopy"
$colItems = (Get-ChildItem $startFolder | Measure-Object -property length -sum)
"$startFolder -- " + "{0:N2}" -f ($colItems.sum / 1MB) + " MB" >> report.txt
$fItems = $(Get-ChildItem $startFolder\*.* | Sort-Object -Property length -Descending)
foreach ($f in $fItems)
{
" " + $f.Length + " " + $f.Fullname >> report.txt
}
$colItems = (Get-ChildItem $startFolder -recurse | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object)
foreach ($i in $colItems)
{
$subFolderItems = (Get-ChildItem $i.FullName | Measure-Object -property length -sum)
$i.FullName + " -- " + "{0:N2}" -f ($subFolderItems.sum / 1MB) + " MB" >> report.txt
$fsubItems = $(Get-ChildItem $startFolder\$i\*.* | Sort-Object -Property length -Descending)
foreach ($fsub in $fsubItems)
{
" " + $fsub.Length + " " + $fsub.Fullname >> report.txt
}
}
“>> report.txt” menandakan kalau output disimpan ke file bernama report.txt. Jika “>> report.txt” dihilangkan ouput akan ditampilkan di command prompt.
#Case 5 : Akan diketemukan
Solution : akan diselesaikan
Saya menambah satu category di blog ini yaitu : Scripting&Automation , akan di update disana. that’s plan 😀 .
#yogyakarta , Jan 06 2013
