Unix-wayКак сграбить скешированное в браузере видео - unix-way метод...

Для граба видео с видеохостингов вроде youtube.com используют различные плагины, к примеру VideoDownloadHelper и подобные. Однако последние не всегда справляются со своими функциями. Здесь можно вооружится свойством unix, заключающееся в том, что абсолютно все ресурсы система рассматривает как файлы. Будь то выделенная физическая память, видеокамера, USB-свисток и т.д.

Пояснять идею в деталях предоставлю автору:
mydebianblog.blogspot.com/2012/04/c-youtube-unix.html

От себя добавлю однострочный скрипт облегчающий граб флеш-роликов:
fl="`lsof -n | grep Flash`" && fn="`echo $fl | awk '{print $9}'`" && cd "/proc/`echo "$fl" | awk '{print $2}'`/fd" && cp "`ls -l | grep "$fn" | awk '{print $9}'`" ~/video.flv

Все, что нужно, это зайти браузером на страницу с роликом, запустить его воспроизведение и, дождавшись полной загрузки в кеш, скопипастить и выполнить приведенную строчку в консоль… после этого(при удачном стечении=) в домашней папке появится файл: video.flv
Проверял на chromium, но должно работать с любым браузером. Единственное требование — на момент запуска скрипта в браузере должна-быть открыта только одна страница с флеш-роликом! Если будет открыто несколько страниц с роликами или несколько браузеров с открытыми роликами, скрипт отработает с ошибкой.

Переименовать и переместить в нужную папку — дело вкуса и цвета пользователя,
к примеру:
mv ~/video.flv '/home/user/Видео/+100500.flv'
  • avatar
  • terra
  • 2095
  • +15
  • 19 апреля 2012, 18:46
  • 14

ПрограммированиеМой первый "Hello World" для GTK+ или Си-шная реализация скрипта Grub-Configurator

Представляю Си-шный вариант реализации своей утилиты grub-config на Gtk+
Шапками сходу забрасывать будет некрасиво ибо только начал изучать GTK+ и системные вызовы Linux.
Для компиляции необходимы devel-пакеты gtk+-2.0 и imagemagick, а в роли редактора простенького проекта будет незаменим geany.
Deb-пакет
Исходник:
#include <gtk/gtk.h>
#include <string.h>
#include <stdio.h>
#include <wand/MagickWand.h>
#include <X11/extensions/Xrandr.h>

typedef struct{
  gchar   *filepath;	//wallpaper image file path
  gint     timeout;		//timeout count
  gboolean savedefault;	//savedefault flag
  gboolean recovery;	//recoveri flag
  gboolean memtest;		//memtest flag
  gboolean playsound;	//playsound flag
  gboolean wallpaper;	//wallpaper flag
  gchar   *resolution;	//string-resolution
  gint     x_res;		//x-resolution
  gint     y_res;		//y-resolution
  glong	   lfSize;		//last file size
  gchar	  *t_image_name;//temporary image-file name
  gint	   x_preview;	//width preview image
  gint	   y_preview;	//height preview image
  gchar   *work_file_buf;//file
  gchar   *file_buf;	//	buffers
} grub_config;

const gchar *STRING_1="Обращаю внимание!\n\
Утилита, изменяет файлы конфигурации загрузчика.\
В маловераятном случае но это может привести к потере \
операционной системой возможности нормально загружаться!\
Поэтому как говориться: все делаете на свой страх и риск!\
Начальный конфиг сохраняется в - /etc/default/grub_save\n\
Никакие изменения не вступают в силу вплоть до подтверждения \
выбранных настроек и ввода пароля!";

const gint file_path_len=1024;
const gint FilterCount=4;
const gchar *FileFilters[]={"*.jpg", "*.JPG", "*.png", "*.PNG"};
const gchar *logo_path="/usr/share/icons/hicolor/128x128/apps/grub-config.png"; // Иконка - лого
const gchar *DefaultImagePath="/usr/share/backgrounds"; // Дефолтная папка с обоями
const gchar *def_grub="/etc/default/grub"; // Конфиг Grub
const gchar *boot_img="/boot/grub/boot.jpg"; // Целевой файл обоев
const gchar *default_melody="480 900 2 1000 2 800 2 400 2 600 3"; // Мелодия бипа
const gint win_width=500, win_height=300; // Дефолтные размеры окна
const gint thumb_width=128, thumb_height=64;
const gint default_timeout=3;

//шаблоны поиска-замены-вставки
const gchar *tmpl1  = "GRUB_DEFAULT";
const gchar *tmpl2  = "GRUB_SAVEDEFAULT=true";
const gchar *tmpl3  = "GRUB_TIMEOUT";
const gchar *tmpl4  = "GRUB_DISABLE_LINUX_RECOVERY";
const gchar *tmpl4_1= "GRUB_DISABLE_RECOVERY";
const gchar *tmpl5  = "GRUB_GFXMODE";
const gchar *tmpl6  = "GRUB_BACKGROUND";
const gchar *tmpl7  = "GRUB_INIT_TUNE";
const gchar *tmpl8  = "memtest";

gchar *filepath=NULL, *save_filepath=NULL;
gchar *ScreenResolution=NULL;
GtkWidget *file_button, *color_button, *font_button, *thumb, *chkbx1, *chkbx[5], *button[4], *lebel[7], *spin_button, *resolution;
GtkWindow *main_window=NULL;
GtkFileFilter *GtkFilter=NULL;
GdkPixbuf *PixBuffer=NULL, *PixBuffer_logo=NULL;
GtkEntryBuffer *TextBufferRes=NULL;
grub_config grc;

void MessageBox(const gchar *message){
  GtkWidget *dialog=gtk_message_dialog_new(main_window, \
					GTK_DIALOG_MODAL, \
					GTK_MESSAGE_INFO, \
					GTK_BUTTONS_CLOSE, \
					NULL);
  gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), message);
  gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (dialog);
}

void MessError(const gchar *txt, const gchar *fn){
  const gchar *caption="Error!\n";
  GtkWidget *dialog;
  int size=strlen(caption)+strlen(txt)+strlen(fn)+1;
  gchar *buf=malloc(sizeof(gchar)*size);
  sprintf(buf, "Error!\n%s %s", txt, fn);
  dialog=gtk_message_dialog_new(main_window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, NULL);
  gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), buf);
  gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (dialog);
  g_free(buf);
}

gboolean InputControl(){
  const gchar *sr=gtk_entry_get_text(GTK_ENTRY(resolution));
  memset(ScreenResolution, 0, 20*sizeof(gchar));
  strcpy(ScreenResolution, sr);

  const int max=9;
  gchar sw[max], sh[max], tmp;
  int i,w=0,h=0,res_x=0,res_y=0;
  for(i=0; i<max; i++) sw[i]=sh[i]=0;
  gboolean res=TRUE;
  for(i=0; i<max; i++){
	  tmp=ScreenResolution[i];
	  if(tmp>='0' && tmp<='9')
		if(res) sw[w++]=tmp;
		else    sh[h++]=tmp;
	  else if (tmp) res=FALSE;
  }
  if(res || w>4 || w<3 || h>4 || h<3) return FALSE;
  w=0; h=0;
  for(i=0; i<max; i++){
  if(sw[i]) {res_x*=10; res_x+=(sw[i]-'0');}
  if(sh[i]) {res_y*=10; res_y+=(sh[i]-'0');}
  }
  grc.x_res=res_x; grc.y_res=res_y;
  strcpy(ScreenResolution, sw); strcat(ScreenResolution, "x"); strcat(ScreenResolution, sh);
  grc.resolution=ScreenResolution;
  gtk_entry_set_text(GTK_ENTRY(resolution), ScreenResolution);
  return TRUE;
}

gchar *FileToBuffers(const gchar *filepath){
  glong lSize, result;
  FILE *pFile=fopen(filepath, "r");
  if (pFile!=NULL){
	fseek (pFile , 0 , SEEK_END);
	lSize = ftell (pFile);
	g_print("opening file name: %s\n",filepath);
	g_print("opening file size: %i\n",(int)lSize);
	rewind (pFile);
	gchar *buffer = g_malloc(sizeof(gchar)*lSize+1);
	if (buffer == NULL) {fclose (pFile); g_free(buffer); return NULL;}
	result = fread (buffer,1,lSize,pFile);
	if (result != lSize) {fclose (pFile); g_free(buffer); return NULL;}
	fclose (pFile);
	grc.lfSize=lSize;
	buffer[lSize]=0;
	return buffer;
  }
  return NULL;
}

void ImageConvert(){ // Обработка изображения
#define ThrowWandException(wand) { char *description; ExceptionType severity; \
  description=MagickGetException(wand,&severity); \
  (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
  description=(char *) MagickRelinquishMemory(description); grc.wallpaper=FALSE; exit(-1);}

  if(!InputControl()) MessError("wrong input screen resolution","");
  MagickBooleanType status;
  MagickWand *magick_wand = NULL;
  DrawingWand *d_wand = NULL;
  PixelWand *p_wand = NULL;
  
  MagickWandGenesis(); /* Read image file */
  magick_wand=NewMagickWand();
  status=MagickReadImage(magick_wand,grc.filepath);
  if (status == MagickFalse) ThrowWandException(magick_wand);

  MagickResetIterator(magick_wand); /* Resize image */
  MagickResizeImage(magick_wand,grc.x_res,grc.y_res,LanczosFilter,1.0);
  /* Write the image then destroy it. */
  status=MagickWriteImages(magick_wand,grc.t_image_name,MagickTrue);
  if (status == MagickFalse) ThrowWandException(magick_wand);
  magick_wand=DestroyMagickWand(magick_wand);
  if(d_wand) d_wand = DestroyDrawingWand(d_wand);
  if(p_wand) p_wand = DestroyPixelWand(p_wand);
  MagickWandTerminus();
}

gboolean my_strcmp(gchar *buf, const gchar *tpl){
  gint i;
  for(i=0; i<strlen(tpl); i++) if(buf[i]!=tpl[i]) return FALSE;
  return TRUE;
}

int f_str(const gchar *tpl){ /* find string */
  gint i, l=strlen(grc.file_buf);

  for(i=0; i<l; i++) if(grc.file_buf[i]==tpl[0] && my_strcmp(grc.file_buf+i, tpl)) return i;
  return 0;
}

int f_str_s(const gchar *tpl){ /*find line content string*/
  int ptr=f_str(tpl);
  if(!ptr) return 0;
  while(grc.file_buf[ptr]!='\n') ptr--;
  return ++ptr;
}

void s_move(gchar *dist, gchar *src, gint len){ // Перенос опред.колич.символов
  gint i;
  for(i=0; i<len; i++) dist[i]=src[i];
}

int next_l(gint ptr){
  while(grc.file_buf[ptr]!='\n')
	if(grc.file_buf[ptr]!='\0') ptr++;
	else {
		grc.file_buf[ptr++]='\n';
		grc.file_buf[ptr]='\0';
		return ptr;
		}
  return ++ptr;
}

gboolean add_str_aft_line(const gchar *tpl, gchar *new){			//добавление строки после найденной по шаблону
  int ptr=f_str_s(tpl);							//ищу строку по шаблону
  if(!ptr) return FALSE;						//выход если строка не найдена
  ptr=next_l(ptr);								//перевожу указатель на след.строку
  s_move(grc.work_file_buf, grc.file_buf, ptr);	//копирую текст до шаблона
  grc.work_file_buf[ptr]='\0';					//завершаю нулем
  strcpy(grc.work_file_buf+ptr, new);			//вставляю новую строку
  if(ptr<strlen(grc.file_buf))				//проверка на конец файла
	strcat(grc.work_file_buf,grc.file_buf+ptr);	//и копирую оставшееся
  strcpy(grc.file_buf, grc.work_file_buf);		//возвращаю результат в основной буфер
  return TRUE;
}

gboolean facs(const gchar *tpl, gchar *new){	//поиск и замена строки
  int ptr=f_str_s(tpl);
  if(!ptr) return FALSE;			//выход если строка не найдена
  s_move(grc.work_file_buf, grc.file_buf, ptr);	//копирую текст до шаблона
  grc.work_file_buf[ptr]='\0';			//завершаю нулем
  strcpy(grc.work_file_buf+ptr, new);		//вставляю новую строку
  ptr=next_l(ptr);				//пареход на следующую строку в источнике
  if(ptr<strlen(grc.file_buf))			//проверка на конец файла
	strcat(grc.work_file_buf,grc.file_buf+ptr);	//и копирую оставшееся
  strcpy(grc.file_buf, grc.work_file_buf);	//возвращаю результат в основной буфер
  return TRUE;
}

gboolean get_line(gchar *buf, const gchar *tpl){//поиск строки содержащей шаблон и копирование её в буфер
  gint ptr=f_str_s(tpl);
  if(!ptr) return FALSE;
  gint dptr=0;
  while(grc.file_buf[ptr]!='\n' && grc.file_buf[ptr]!='\0') buf[dptr++]=grc.file_buf[ptr++];
  buf[dptr]='\0';
  if(!dptr) return FALSE;
  return TRUE;
}

gboolean get_line_parameter_string(gchar *buf, const gchar *tpl){	//поиск строки по шаблону и возврат значения от знака = до первого пробела 
  if(!get_line(buf, tpl)) return FALSE;
  gint ptr;
  for(ptr=0; ptr<strlen(buf); ptr++) if(buf[ptr]=='=') break;
  if(ptr>=strlen(buf)) return FALSE;
  gint dptr=0;
  ptr++;
  while(buf[ptr]!=' ' && buf[ptr]!='\0') buf[dptr++]=buf[ptr++];
  buf[dptr++]='\0';
  return TRUE;
}

gint get_line_parameter_int(gchar *buf, const gchar *tpl){//поиск строки по шаблону и возврат целочисленного значения после символа '='
  if(!get_line_parameter_string(buf, tpl)) return FALSE;
  gint ptr, dig;
  gint res=0, len=strlen(buf);
  for(ptr=0;ptr<len;ptr++){
	dig=buf[ptr]-'0';
	if(dig>9) return 0;
	res=res*10+dig;
	}
  return res;
}

gboolean check_line_on_comment(const gchar *tpl){	//поиск строки по шаблону и проверка на закомментированность
  gint ptr=f_str_s(tpl);							//возвращает FALSE если строки нет или она закоментирована

  if(!ptr) return FALSE;
  while(grc.file_buf[ptr]!='\0' || grc.file_buf[ptr]!='\n'){
	if(grc.file_buf[ptr]==' ') {ptr++; continue;}
	if(grc.file_buf[ptr++]=='#') return FALSE;
	else break;
	}
  return TRUE;
}

void StringRoutine(){ // Обработка файла-конфига
  gchar buf[200];
  if(grc.savedefault){
	sprintf(buf,"%s%s\n",tmpl1,"=saved");	//создаю новую строку
	facs(tmpl1, buf);
	sprintf(buf,"%s\n", tmpl2);			//добавляю,
	if(!facs(tmpl2, buf))					//	если требуется, GRUB_SAVEDEFAULT=true
	  add_str_aft_line(tmpl1, buf);
  }
  else {
	sprintf(buf,"%s%s\n",tmpl1,"=0");		//устанавливаю первоначальное значение
	facs(tmpl1, buf);
	facs(tmpl2, "");
  }

  sprintf(buf,"%s=%i\n", tmpl3, grc.timeout);	//задаю таймаут
  facs(tmpl3, buf);

  *buf='\0';
  if(grc.recovery) strcpy (buf,"#");		//определяюсь с пунктами recovery mode

  if(f_str(tmpl4)){				//поиск и замена ведется по двум шаблонам
	strcat(buf, tmpl4); strcat(buf,"=true\n");// GRUB_DISABLE_LINUX_RECOVERY и GRUB_DISABLE_RECOVERY
	facs(tmpl4, buf);			//потому-шта в разных версиях груба они различаюца
	}
  else  {
	strcat(buf, tmpl4_1); strcat(buf,"=true\n");
	facs(tmpl4_1, buf);
	}

  sprintf(buf,"%s=\"%s\"\n", tmpl7, default_melody);//настраиваю бип
  if(grc.playsound){
	if(!facs(tmpl7, buf)){
		strcat(grc.file_buf, "\n");
		strcat(grc.file_buf, buf);
		}
	}
  else facs(tmpl7, "");

  if(grc.wallpaper){						//обновляю разрешение экрана
	sprintf(buf,"%s=%ix%i\n", tmpl5, grc.x_res, grc.y_res);
	facs (tmpl5, buf);
	sprintf(buf,"%s=%s\n", tmpl6, boot_img);
	if(!facs(tmpl6,buf)){
		strcat(grc.file_buf,"\n");
		strcat(grc.file_buf,buf);			//добавляю в конец GRUB_BACKGROUND=path
		}
	}
  else {
	sprintf(buf,"#%s=640x480\n", tmpl5);
	facs (tmpl5, buf);
	facs(tmpl6,"");
	}
  
  int i=strlen(grc.file_buf);				//удаляю лишние пробелы и перевод строки в конце буфера
  if(grc.file_buf[i-1]){
	i--;
	while(grc.file_buf[i]=='\n' || grc.file_buf[i]==' ') i--;
	grc.file_buf[++i]='\0';
	}
  grc.lfSize=i*sizeof(gchar);
  
  g_print("\n\nСодержимое конфига:\n%s\n\n", grc.file_buf);
}

void MemtestMove(){ //перенос файла memtest86+
// ПОКА ЭТО ПУСТЫШКА. НА ДНЯХ ДОБАВЛЮ
}

static void ApplySettings(){
  const gchar *errprefw="can't writting to file:";
  const gchar *errprefo="missing opening file:";
  
  if( !InputControl()){
	  MessageBox("Error input screen resolution");
	  return;
  }
  /* Контрольно считываю параметры */
  grc.timeout		= gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin_button));
  grc.wallpaper		= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[0]));
  grc.savedefault	= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[1]));
  grc.recovery		= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[2]));
  grc.memtest		= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[3]));
  grc.playsound		= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[4]));
  if(grc.filepath)	grc.wallpaper=TRUE;
  else 			grc.wallpaper=FALSE;

  g_free(grc.file_buf);
  grc.file_buf=FileToBuffers(def_grub);

  if (!grc.file_buf) MessError(errprefo, def_grub);

  gint rnd=87687, len=100; // Буфера и в них имена временных файлов
  gchar *t_img=g_malloc(len);
  gchar *t_wrk=g_malloc(len);
  gchar *t_fsc=g_malloc(len);
  
  grc.work_file_buf=g_malloc(grc.lfSize*2); // Выделяю память для рабочих буферов
  memcpy(grc.work_file_buf, grc.file_buf, grc.lfSize);
  g_free(grc.file_buf);
  grc.file_buf=g_malloc(grc.lfSize*2); // Буфер для нового содержимого конфига
  memcpy(grc.file_buf, grc.work_file_buf, grc.lfSize);
  grc.file_buf[grc.lfSize]=grc.work_file_buf[grc.lfSize]='\0';

  sprintf(t_wrk, "/tmp/wrk_tmp_%i.tmp",rnd);// Имена временных файлов
  sprintf(t_fsc, "/tmp/fsc_tmp_%i.sh",rnd); 
  
  StringRoutine(); // Обработка файла-конфига
  if(grc.wallpaper) ImageConvert(); // Обработка изображения
  MemtestMove();
  
  long lWrite;
  FILE *pFile=fopen(t_wrk, "wb"); // Сбрасываю буфер с новым содержимым во временный файл
  if (pFile) lWrite=fwrite (grc.file_buf , 1 , grc.lfSize, pFile );
  if(pFile && lWrite==grc.lfSize){
	fclose (pFile); pFile=NULL;
	gchar *t_scr=malloc(200*sizeof(gchar)); // Создаю скрипт, чтобы не вызывать gksu по несколько раз
	if(grc.wallpaper) // Если надо скопировать картинку
		 sprintf(t_scr,"#!/bin/sh\nmv %s %s\ncp %s %s_save\nmv %s %s\nchown root:root %s\nupdate-grub",
							grc.t_image_name, boot_img, def_grub, def_grub, t_wrk, def_grub, def_grub);
	else sprintf(t_scr,"#!/bin/sh\ncp %s %s_save\nmv %s %s\nchown root:root %s\nupdate-grub",
							def_grub, def_grub, t_wrk, def_grub, def_grub);
g_print("\n\nТекст скрипта:\n%s\n\n", t_scr);	
	gboolean fl=FALSE;
	glong sSize=strlen(t_scr)*sizeof(gchar), sWrite=0;
	FILE *sFile=fopen(t_fsc, "wb"); // Создаю файл со скриптом
    if (sFile) sWrite=fwrite (t_scr , 1, sSize , sFile );
    if (!sFile || sSize!=sWrite) MessError(errprefw, t_fsc);
	else {
		fclose (sFile); sFile=NULL; fl=TRUE;
		sprintf(t_img,"chmod +x %s", t_fsc);
		system(t_img);
		sprintf(t_img,"gksu %s", t_fsc); // Создаю команду запуска скрипта
		system(t_img); // Выполняю эту команду
		}
	if (sFile) fclose (sFile);
	if (fl) remove (t_fsc); // Удаляю файл со скриптом
	g_free(t_scr); // Освобождаю буфер скрипта
  }
  else {
	MessError(errprefw, t_wrk);
	fclose (pFile);
  }

  g_free(t_img); g_free(t_wrk); g_free(t_fsc);// Возвращаю память куче
}

void UpdatePath(){
  if( ! grc.filepath ) return;
  if(!filepath) filepath=g_malloc((size_t)file_path_len);
  strcpy(filepath, grc.filepath);
  int i, len=strlen(grc.filepath);
  for(i=len; i>0; i--) if (filepath[i]=='/') {
	  filepath[i]='\0'; break;
  }
}

gboolean LoadImagePrewiev(){
//  GError *error;
  PixBuffer=gdk_pixbuf_new_from_file_at_size(grc.filepath, thumb_width, thumb_height, NULL);// &error);
  gtk_image_set_from_pixbuf(GTK_IMAGE(thumb), PixBuffer);
  return TRUE;
}

gboolean ShowURL(GtkAboutDialog *about, const gchar *url, gpointer data){
  gtk_show_uri(NULL, url, 0, NULL);
  return TRUE;
}

void AboutDialog(GtkWidget * widget, gpointer data){
  const gchar* autor_a[]={
	  "Terechov Wladislav\n Conquistador ™\n e-mail: asgrem@gmail.com\nhttp://my.mail.ru/community/win_xp/",
	  NULL};
  const gchar* name_a="About";
  const gchar* prog_a="Grub Configurator";
  const gchar* vers_a="0.1";
  const gchar* copy_a="free software";
//  const gchar* site_a="http://my.mail.ru/community/win_xp/";
  const gchar* coms_a="Configurator of GRand Unified Bootloader";
  GtkAboutDialog *dialog=GTK_ABOUT_DIALOG(gtk_about_dialog_new());
  GdkPixbuf *pict=gdk_pixbuf_new_from_file(logo_path, NULL);

  gtk_about_dialog_set_name(dialog, name_a);
  gtk_about_dialog_set_program_name(dialog, prog_a);
  gtk_about_dialog_set_version(dialog, vers_a);
  gtk_about_dialog_set_copyright(dialog, copy_a);
  gtk_about_dialog_set_comments(dialog, coms_a);
  gtk_about_dialog_set_authors(dialog, autor_a);
  gtk_about_dialog_set_logo(dialog, pict);

  g_signal_connect(G_OBJECT(dialog), "activate-link", G_CALLBACK(ShowURL), NULL);
  
  gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (GTK_WIDGET(dialog));
}

GtkWidget *LabelSet(const gchar *string){
  GtkWidget *label=gtk_label_new(string);
  gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
  gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD); //PANGO_WRAP_CHAR, PANGO_WRAP_WORD_CHAR
  return label;
}

static void AttentionMessage(GtkWidget * widget, gpointer data){
  MessageBox(STRING_1);
}

static void PriviewImage(GtkWidget * widget, gpointer data){
  if(!grc.filepath) return;
  ImageConvert();
  GtkWidget *image = gtk_image_new();
  GdkPixbuf *pb=gdk_pixbuf_new_from_file_at_size(grc.t_image_name, grc.x_preview, grc.y_preview, NULL);// &error);
  gtk_image_set_from_pixbuf(GTK_IMAGE(image), pb);

  GtkWidget *dialog=gtk_dialog_new_with_buttons ("Preview", main_window,
	GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
	NULL);
  GtkWidget *box=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
  gtk_box_pack_start(GTK_BOX(box), image, TRUE, TRUE, 0);
  gtk_widget_show(image);
  gtk_dialog_run(GTK_DIALOG(dialog));
  gtk_widget_destroy (GTK_WIDGET(dialog));
}

static gboolean delete_event(GtkWidget * widget, GdkEvent * event, gpointer data){
  g_print("Delete event occurred\n");
  return FALSE;
}

static void destroy(GtkWidget * widget, gpointer data){
  gtk_main_quit();
}

static void toogle_callback(GtkWidget *togglebutton, gboolean *data){ //обработка сигналов от чек-батонов
  *data=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton));
  gchar *labl = *data ? "Enable" : "Disable";
  gtk_button_set_label(GTK_BUTTON(togglebutton), labl);
  if( togglebutton == chkbx[0] ){								//при изменении состояния кнопки обоев...
	if(*data){
		grc.filepath=save_filepath;
		UpdatePath();
		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_button), filepath);
		if(grc.filepath) LoadImagePrewiev();
		gtk_entry_set_editable(GTK_ENTRY(resolution), TRUE);
		}
	else {
		if(!filepath) {
			filepath=g_malloc((size_t)file_path_len);
			}
		strcpy(filepath, DefaultImagePath);
		grc.filepath=NULL;
		gtk_image_set_from_pixbuf(GTK_IMAGE(thumb), PixBuffer_logo);
		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_button), filepath);
		gtk_entry_set_editable(GTK_ENTRY(resolution), FALSE);
		}
	}	
}

void set_toggle_button_state(GtkWidget *button, gboolean *flag) { // Установка начального состояния тоггл-кнопок
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), *flag);
  toogle_callback(button, flag);
}

void file_selected_event(GtkFileChooserButton *fc_button, gpointer user_data) {
  if(grc.filepath)g_free(grc.filepath);
    save_filepath=grc.filepath=gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fc_button));
    grc.wallpaper=TRUE;										//устанавливаю кнопку обоев в "enable"
    set_toggle_button_state(chkbx[0],&grc.wallpaper);
}

void update_parameter(){ //обновление параметров согласно файлу-конфигу grub
  gchar *buf=g_malloc(256);
  get_line_parameter_string(buf, tmpl1);
  if(strcmp(buf,"saved") || f_str(tmpl2))grc.savedefault=TRUE;

  grc.timeout=get_line_parameter_int(buf, tmpl3);

  if(!check_line_on_comment(tmpl4) && !check_line_on_comment(tmpl4_1)) grc.recovery=TRUE;
  gboolean res1=check_line_on_comment(tmpl4);
  gboolean res2=check_line_on_comment(tmpl4_1);
  g_print("%s - %i\n%s - %i", tmpl4, (int)res1, tmpl4_1, (int)res2);

  if(f_str(tmpl6)){
	grc.wallpaper=TRUE;
	if(get_line_parameter_string(buf,tmpl6)){
		save_filepath=grc.filepath=g_malloc(file_path_len);
		strcpy(grc.filepath, buf);
		}}
  if(f_str(tmpl7)) grc.playsound=TRUE;
  
  g_free(buf);
}

int main(int argc, char ** argv){
  GtkWidget * window;
  GtkWidget * box;
  gint i;
  
  gtk_init(&argc, &argv);
  ScreenResolution=g_malloc(20); // Выделяю буфер для строчки с разрешением

  /* Определяю разрешение экрана и превью */
  int nsizes;
  Display *dpy = XOpenDisplay(NULL);
  XRRScreenSize *ss = XRRSizes(dpy, 0, &nsizes);
  grc.x_res=ss->width; grc.y_res=ss->height;
  XCloseDisplay(dpy);
  grc.x_preview = grc.x_res/3*2;
  grc.y_preview = grc.y_res/3*2;

  const gchar *temp_image_name="/tmp/img_tmp_file.jpg";// Имя временного файла-изображения
  grc.t_image_name=g_malloc((strlen(temp_image_name)+1)*sizeof(gchar));
  strcpy(grc.t_image_name, temp_image_name); 

  GtkFilter = gtk_file_filter_new (); // Инициализация файловых фильтров
  gtk_file_filter_set_name(GtkFilter, "Images");
  for(i=0; i<FilterCount; i++) gtk_file_filter_add_pattern (GtkFilter, FileFilters[i]);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  main_window = GTK_WINDOW(window); // Сохраняю идентификатор главного окна глобально для диалогов

  gtk_window_set_default_size (GTK_WINDOW (window), win_width, win_height);
  gtk_window_set_title(GTK_WINDOW(window), "Grub Configurator");
  gtk_container_set_border_width(GTK_CONTAINER(window), 10);

  g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);

  box=gtk_table_new(10, 2, FALSE);
  gtk_container_add(GTK_CONTAINER(window), box);

  grc.file_buf=FileToBuffers(def_grub);
  grc.timeout		= default_timeout;
  grc.wallpaper=grc.savedefault=grc.recovery=grc.memtest=grc.playsound=FALSE;
  update_parameter();

/* лебел - выбор изображения	1 строчка */
  lebel[0]=LabelSet("Background image:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[0], 0, 1, 0, 1);
  gtk_widget_show(lebel[0]);
  // чекбокс background
  chkbx[0]=gtk_toggle_button_new();
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[0], 1, 2, 0, 1);
  g_signal_connect(G_OBJECT(chkbx[0]), "toggled", G_CALLBACK(toogle_callback), &grc.wallpaper);
  gtk_widget_show(chkbx[0]);

/* иконка предпросмотра и кнопка выбора файла	2 строчка */
  thumb = gtk_image_new();
  PixBuffer_logo=PixBuffer=gdk_pixbuf_new_from_file_at_size(logo_path, thumb_width, thumb_height, NULL);// &error);
  if(grc.filepath) LoadImagePrewiev();
  else gtk_image_set_from_pixbuf(GTK_IMAGE(thumb), PixBuffer);
  button[3]=gtk_button_new();
  gtk_button_set_relief(GTK_BUTTON(button[3]), GTK_RELIEF_NONE);
  gtk_button_set_focus_on_click(GTK_BUTTON(button[3]), FALSE);
  gtk_button_set_image(GTK_BUTTON(button[3]), thumb);
  g_signal_connect(G_OBJECT(button[3]), "clicked", G_CALLBACK(PriviewImage), window);
  gtk_table_attach_defaults(GTK_TABLE(box), button[3], 0, 1, 1, 2);
  gtk_widget_show(button[3]);
  
  file_button=gtk_file_chooser_button_new("Select Image File", GTK_FILE_CHOOSER_ACTION_OPEN); //GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
  gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_button), DefaultImagePath);
  gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON (file_button), 15);
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (file_button), GtkFilter);
  g_signal_connect(G_OBJECT(file_button), "file-set", G_CALLBACK(file_selected_event), NULL);
  gtk_table_attach_defaults(GTK_TABLE(box), file_button, 1, 2, 1, 2);
  gtk_widget_show(file_button);

/* выбор разрешения				3 строчка */
  lebel[1]=LabelSet("Input default screen resolution:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[1], 0, 1, 2, 3);
  gtk_widget_show(lebel[1]);
  gchar res[20];
  sprintf(res,"%ix%i", grc.x_res, grc.y_res);
  TextBufferRes=gtk_entry_buffer_new(res, strlen(res));
  resolution=gtk_entry_new_with_buffer(TextBufferRes);
  gtk_entry_set_max_length(GTK_ENTRY(resolution), 9);
  gtk_entry_set_editable(GTK_ENTRY(resolution), FALSE);
  gtk_table_attach_defaults(GTK_TABLE(box), resolution, 1, 2, 2, 3);
  gtk_widget_show(resolution);
  
/* спин timeout					4 строчка */
  lebel[2]=LabelSet("Grub timeout:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[2], 0, 1, 3, 4);
  gtk_widget_show(lebel[2]);
  spin_button=gtk_spin_button_new_with_range(0,120,1); // Добавляю спинер
  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), grc.timeout);
  gtk_table_attach_defaults(GTK_TABLE(box), spin_button, 1, 2, 3, 4);
  gtk_widget_show(spin_button);
  
/* чекбокс savedefault			5 строчка */
  lebel[3]=LabelSet("Save last item as default:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[3], 0, 1, 4, 5);
  gtk_widget_show(lebel[3]);
  chkbx[1]=gtk_toggle_button_new_with_label ("Disable");
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[1], 1, 2, 4, 5);
  g_signal_connect(G_OBJECT(chkbx[1]), "toggled", G_CALLBACK(toogle_callback), &grc.savedefault);
  gtk_widget_show(chkbx[1]);

/* чекбокс recovery mode		6 строчка */
  lebel[4]=LabelSet("Items \"Recovery mode\":");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[4], 0, 1, 5, 6);
  gtk_widget_show(lebel[4]);
  chkbx[2]=gtk_toggle_button_new_with_label ("Disable");
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[2], 1, 2, 5, 6);
  g_signal_connect(G_OBJECT(chkbx[2]), "toggled", G_CALLBACK(toogle_callback), &grc.recovery);
  gtk_widget_show(chkbx[2]);
  
/* чекбокс memtest86+			7 строчка */
  lebel[5]=LabelSet("Items \"memtest86+\":");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[5], 0, 1, 7, 8);
  gtk_widget_show(lebel[5]);
  chkbx[3]=gtk_toggle_button_new_with_label ("Disable");
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[3], 1, 2, 7, 8);
  g_signal_connect(G_OBJECT(chkbx[3]), "toggled", G_CALLBACK(toogle_callback), &grc.memtest);
  gtk_widget_show(chkbx[3]);
  
/* чекбокс playsound			8 строчка */
  lebel[6]=LabelSet("Play sound on start:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[6], 0, 1, 8, 9);
  gtk_widget_show(lebel[6]);
  chkbx[4]=gtk_toggle_button_new_with_label ("Disable");
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[4], 1, 2, 8, 9);
  g_signal_connect(G_OBJECT(chkbx[4]), "toggled", G_CALLBACK(toogle_callback), &grc.playsound);
  gtk_widget_show(chkbx[4]);

/* кнопка Read My				9 строчка */
  button[0]=gtk_button_new_with_label("Read my!");
  gtk_table_attach_defaults(GTK_TABLE(box), button[0], 0, 2, 9, 10);
  g_signal_connect(G_OBJECT(button[0]), "clicked", G_CALLBACK(AttentionMessage), &button[0]);
  gtk_widget_show(button[0]);
  gtk_container_set_focus_child(GTK_CONTAINER(box), button[0]);			//устанавливаю фокус на кнопку ReadMy

/* кнопка About					10 строчка */
  button[1]=gtk_button_new_with_label("About");
  gtk_table_attach_defaults(GTK_TABLE(box), button[1], 0, 1, 10, 11);
  g_signal_connect(G_OBJECT(button[1]), "clicked", G_CALLBACK(AboutDialog), &button[1]);
  gtk_widget_show(button[1]);

// кнопка Apply
  button[2]=gtk_button_new_with_label("Apply settings!");
  gtk_table_attach_defaults(GTK_TABLE(box), button[2], 1, 2, 10, 11);
  g_signal_connect(G_OBJECT(button[2]), "clicked", G_CALLBACK(ApplySettings), &button[1]);
  gtk_widget_show(button[2]);
  
  set_toggle_button_state(chkbx[0], &grc.wallpaper); //"нажимаю" кнопки согласно конфига
  set_toggle_button_state(chkbx[1], &grc.savedefault);
  set_toggle_button_state(chkbx[2], &grc.recovery);
  set_toggle_button_state(chkbx[3], &grc.memtest);
  set_toggle_button_state(chkbx[4], &grc.playsound);
 
  gtk_widget_show(box);
  gtk_widget_show(window);
  gtk_main();
  
  g_free(grc.t_image_name);
  if(ScreenResolution) g_free(ScreenResolution);
  if(grc.filepath)  g_free(grc.filepath);
  if(filepath)  g_free(filepath);
  if(save_filepath!=grc.filepath && save_filepath)  g_free(save_filepath);
  return 0;
}
  • avatar
  • terra
  • 1963
  • +35
  • 21 января 2012, 22:11
  • 12

Unix-wayBash scripts: nautilus - пакетный ресайзинг изображений

Утилита может пригодится web-разработчикам да и просто в быту. Скрипт, используя возможности ImageMagic, изменяет размер изображений на заданный пользователем в пакетном режиме и сохраняет их во вложенную папку, не изменяя исходных файлов. Можно также добавить текстовую подпись на все изображения. Картинка не изменяет пропорций и, при их несоответствии заданным размерам, выполняется либо ресайз по наименьшей стороне с подрезкой «излишков» либо ресайз по наибольшей стороне с добавлением черных полей.
Скрипт может работать как автономно так и дополнением к менеджеру файлов Nautilus.

deb-пакет добавляет команду resizer в /usr/bin и ссылку на него в Nautilus->Сценарии->Пакетное изменение размера изображений

Исходник
#!/bin/bash
# resizer - Multi Picture Resizer - nautilus script
# written by Conquistador

TFN="/tmp/tmp$$" # temporary file
TFN1="${TFN}-1"
FTR="*.png *.PNG *.jpg *.JPG" # фильтры для zenity --file-selection
FTM="png|jpg" # фильтры для собственных циклов
BGRDCLR=black # цвет фона
TXTCLR=blue # цвет текста
QUALITY=92 # качество сжатия

error() # вывод ошибки -> выход
{
zenity --info --title="Ё-маё!" --text="Ошибка: ${1}!" --timeout=5;
if [ -f ${TFN} ];then rm -f ${TFN};fi
if [ -f ${TFN1} ];then rm -f ${TFN1};fi
exit 1
}

if [ -z "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" ]; then
	NAUTILUS_SCRIPT_SELECTED_FILE_PATHS=$(zenity --file-selection --multiple --file-filter="${FTR}" --filename="${HOME}" --title="Выбери файлы")
	if [ -z "${NAUTILUS_SCRIPT_SELECTED_FILE_PATHS}" ];then error "ничего не выбрано"; fi
	IFS=$'|'
else
	IFS=$'\n'
fi
echo -n > "$TFN"
max=0
for name in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS; do
	echo "$(basename ${name})" >> "$TFN"
	if [ $max -eq 0 ];then folder="$(dirname ${name})";fi
	let max++	
done
unset IFS

# Корректирую список - фильтрую файлы и удаляю пустые строки.
echo -n > "$TFN1"
IFS=$'|'
for e in ${FTM}; do cat "${TFN}" | grep -i .$e >> "$TFN1"; done
unset IFS
sed -i '/^$/d' "$TFN1"
max=$(cat "$TFN1"| wc -l)
[ $max -eq 0 ] && error "нет файлов-изображений для обработки!"

# Спрашиваю размер
_x=$(xrandr | sed -n 's/.\{0,\}current \([0-9]\{1,\}\) x [0-9]\{1,\}.\{0,\}/\1/g;p;q')
_y=$(xrandr | sed -n 's/.\{0,\}current [0-9]\{1,\} x \([0-9]\{1,\}\).\{0,\}/\1/g;p;q')
res=$(zenity --entry --entry-text="${_x}x${_y}" --title="Размер изображений" --text="Введи требуемый размер изображений (например 320x240):")
if [ -z ${res} ]; then error "не выбран размер";fi
res=${res//[X ч Ч х Х \[]/x} # Корректирую сепаратор
if [ "x$(echo ${res} | grep "x")" = "x" ];then error "неверный ввод";fi
width=$(echo "$res" | cut -d"x" -f1 -s) # проверка на пустые значения
height=$(echo "$res" | cut -d"x" -f2 -s)
if [ -z ${width} ] || [ -z ${height} ];then error "не указан один из параметров размера"; fi
geometry=$res

_ext=''
zenity --text="При несоответствии пропорций..." --title="Пропорции" --ok-label="Обрезать изображение" --cancel-label="Добавить пустые поля" --question && _ext='^'

# Спрашиваю автограф
agph=$(zenity --entry --entry-text="Conquistador ™" --title="Автограф" --text="Введи текст подписи, если не нужно оставь поле пустым или нажми - отмена")
if [ $? -ne 0 ]; then agph=""; fi

dist_folder="${folder}/${geometry}"
mes="Всего к обработке: $max файла(ов)\n\
Выбрана папка: ${folder}\n\
Целевая папка: ${dist_folder}\n\
Выбранный размер: ${geometry}
Автограф: ${agph}"
res=0
zenity --text="$mes" --title="Все верно?" --ok-label="Начать" --cancel-label="Отменить" --question && res=1
if [ $res -eq 0 ];then error "отменено"; fi

# Создаю целевую папку
[ -d "${dist_folder}" ] || mkdir ${dist_folder}

# Обнуляю счетчик для прогресс-бара
count=0;
IFS=$'\n'
for i in $(cat "$TFN1"); do
	echo "# Обрабатываю: ${i}"
	# создаю новое имя файла удаляя старый и добавляя новый
	# суффикс ШИРИНАxВЫСОТА и заменяя пробелы на символы подчеркивания
	separator="x X х Х"
	new_name=${i//[- _][0-9][0-9][0-9][0-9][$separator][0-9][0-9][0-9][0-9]/}
	if [ "$new_name" = "$i" ];then
	  new_name=${i//[- _][0-9][0-9][0-9][0-9][$separator][0-9][0-9][0-9]/}
	  if [ "$new_name" = "$i" ];then
	    new_name=${i//[- _][0-9][0-9][0-9][$separator][0-9][0-9][0-9]/}
	    if [ "$new_name" = "$i" ];then
	      new_name=${i//[0-9][0-9][0-9][0-9][$separator][0-9][0-9][0-9][0-9]/}
	      if [ "$new_name" = "$i" ];then
		new_name=${i//[0-9][0-9][0-9][0-9][$separator][0-9][0-9][0-9]/}
		if [ "$new_name" = "$i" ];then
		  new_name=${i//[0-9][0-9][0-9][$separator][0-9][0-9][0-9]/}
	fi fi fi fi fi
	new_name="$(echo ${new_name// /_} | sed 's/\(.*\)\(\....\)/\1-'$geometry'\2/')"

	# Собственно конвертирование картинок
	if [ "x${agph}" = "x" ]; then
		convert "${folder}/${i}" -resize ${geometry}${_ext} -background ${BGRDCLR} -compose Copy -gravity Center -extent ${geometry} -quality ${QUALITY} "${dist_folder}/${new_name}"
	else
		convert "${folder}/${i}" -resize ${geometry}${_ext} -background ${BGRDCLR} -compose Copy -gravity Center -extent ${geometry} -font URW-Palladio-Bold-Italic -gravity South -fill ${TXTCLR} -pointsize 20 -annotate +5+5 "${agph}" -quality ${QUALITY} "${dist_folder}/${new_name}"
	fi
	if [ $? -ne 0 ]; then
		echo "# Ошибка!!!\tНе могу обработать: ${i}"
		sleep 4
	fi    
	let count++
	echo $(($count * 100 / $max))
done | zenity --progress --width=500 --title="Изменение размера $max файла(ов)" --auto-close --auto-kill --percentage=0
unset IFS

rm -f ${TFN} ${TFN1} # удаляю временные файлы
nautilus "${dist_folder}"&
exit 0
  • avatar
  • terra
  • 1669
  • +28
  • 13 января 2012, 23:13
  • 10

Интернетинтерактивные скриншоты

Бродил сегодня по блогам «всемирной паутины»и нашёл интересную фишку «интерактивные скриншоты» Thinglink.



[ Читать дальше... ⇒ ]
  • avatar
  • nik-s76
  • 1577
  • +18
  • 11 января 2012, 18:11
  • 3

Unix-wayНастраиваем Grub2

Занялся от праздничного безделья разноскриптовой писаниной. Выкладываю свой сегодняшний «релиз»=) Утилитка сурьёзно обозвал grub-config. Она умеет немного «прилизывать» Grub2, т.е. упрощает наведение марафеты на сей загрузчик. Утилита мною протестирована в Debian Sid, Debian Squeeze, Ubuntu 10.10 и Linux Mint 12 где выполняла все команды: апорт, фас и т.д. вполне адекватно.

[ Читать дальше... ⇒ ]
  • avatar
  • terra
  • 3256
  • +30
  • 09 января 2012, 02:16
  • 5

Unix-wayУстановка программ с Launchpad.net в Debian

Проект launchpad.net был запущен в 2004 году компанией Cannonical для управления свободными проектами поддерживающими Ubuntu. В Ubuntu по такому случаю добавлена команда add-apt-repository. Команда осуществляет простое добавление, не включенных в основные ветки, репозиториев персональных проектов launchpad, и автоматически добавляет ключи безопасности в систему управления пакетами.
Ubuntu построена на Debian и поэтому большинство программ с ланчпада с равным успехом работают и в последнем. Есть только одно неприятное но — приводимые убунтоводами команды типа:
sudo add-apt-repository ppa:blabla/ppa дебиан не понимает.
Нижеприведенный скрипт в некотором роде решает эту проблему, стоит только добавить его под именем add-apt-repository в папку /usr/sbin.
deb-пакет

[ Читать дальше... ⇒ ]
  • avatar
  • terra
  • 3357
  • +32
  • 06 января 2012, 23:51
  • 4

Unix-wayКак установить и настроить систему виртуализации KVM на Linux Ubuntu

В статье показано как установить и использовать KVM для запуска виртуальных машин на сервере с Ubuntu 11.10. Не даю никаких гарантий, что это будет работать для Вас!



[ Читать дальше... ⇒ ]
  • avatar
  • pashtuun
  • 16783
  • +14
  • 20 ноября 2011, 08:18
  • 1

Unix-wayПоднимаем веб сервер на Ubuntu 11.10 с панелью управления ISPConfig 3 (1 часть)

В статье показано как подготовить Ubuntu 11.10 в качестве сервера с панелью управления ISPConfig 3. Рассмотрена настройка и установка: Apache, почтового сервера Postfix, MySQL, BIND или MyDNS, PureFTPd, SpamAssassin, ClamAV, и многое другое.

Обратите внимание — это не будет работать на ISPConfig 2, а будет только на ISPConfig 3! Не даю никаких гарантий, что это будет работать у Вас.

ISPConfig 3 Manual


>>>Скачать руководство по ISPConfig 3<<<

Содержит около 300 страниц и охватывает основные концепции ISPConfig (для администраторов, реселлеров и клиентов), объясняет как установить и обновить ISPConfig 3, а также предоставляет обучающие материалы для наиболее распространенных задач в ISPConfig 3.

Приложение мониторинг ISPConfig для Android


С помощью SPConfig Monitor App можно проверить состояние сервера и выяснить, если службы не работают. Вы можете проверить TCP и UDP порты и пинг до серверов. В дополнение к этому можно запросить подробности сервера с ISPConfig (обратите внимание ISPConfig должен быть с поддержкой ISPConfig Monitor App, на сегодняшней день версия 3.0.3.3); Можно просмотреть например, почтовые логи, почтовые очереди, процессор и память, использование дискового пространства, операционную систему и т.д.

Для загрузки приложения и инструкций по использованию, посетите www.ispconfig.org/ispconfig-3/ispconfig-monitor-app-for-android/.




[ Читать дальше... ⇒ ]
  • avatar
  • pashtuun
  • 27862
  • +17
  • 22 октября 2011, 11:35
  • 28

Unix-wayPHP-FPM+Nginx - безопасное выполнение PHP от пользователей в Debian или Ubuntu

Если вы хотите использовать Nginx и PHP-FPM для раздачи виртуального хостинга, вы должны составить политику безопасности. В среде Apache/PHP можно использовать Suexec и/или suPHP, для того чтобы выполнять PHP скрипты от отдельных учетных записей пользователей, а не пользователя системы, как в случае с www-data. Для PHP-FPM нет такого понятия, однако к счастью PHP-FPM позволяет создать «пул» для каждого веб-сайта, помогая сделать выполнение PHP скриптов от разных пользователей/групп.



[ Читать дальше... ⇒ ]
  • avatar
  • pashtuun
  • 10942
  • +12
  • 24 сентября 2011, 12:54
  • 7

Unix-wayОбычная проверка подлинности HTTP в Nginx

В статье показано, как можно использовать базовую HTTP аутентификацию в Nginx, чтобы защитить паролем директории на вашем сервере или даже закрыть весь сайт. На Nginx это эквивалентно обычной проверки подлинности HTTP в Apache с использованием .htaccess и .htpasswd.

Сайт будет www.example.com, находящийся в папке /var/www/www.example.com/web/, виртуальный хост в /etc/nginx/sites-enabled/www.example.com.vhost. Под паролем будет одна папка /var/www/www.example.com/web/test/.

Нужно сделать файл с паролями, где перечислены пользователи и их пароли (в зашифрованном виде). Для создания такого файла, можно либо использовать инструмент Apache htpasswd, или Python скрипт от сюда.



[ Читать дальше... ⇒ ]
  • avatar
  • pashtuun
  • 4250
  • +21
  • 22 сентября 2011, 11:25
  • 3