LINUX.ORG.RU

Сообщения ip1981

 

Шаман, протрите монитор, будьте любезны

Форум — Linux-org-ru
ip1981
()

I'm rejecting scantaylor

Форум — Talks

http://osdir.com/ml/ubuntu-archive/2009-05/msg00413.html

I'm rejecting scantaylor.

It includes an icon arrow_in which is licenced under creative commons. This is compiled into a binary which is otherwise under the GPL. Since these licences are incompatible the binary can not be distributed

Копирайт в принципе порочен, и GPL тут не спасёт.

ip1981
()

Патч для Критикал Масс

Форум — Games

Патч для Критикал Масс (http://criticalmass.sourceforge.net/), дающий бессмертие.

Добавляет параметр HeroImmortal. Его надо вписать в файл ~/.critter/config.txt, например так: set HeroImmortal = true

Так очень хорошо тренироваться.

diff -urdbN CriticalMass-0.9.11/game/Hero.cpp CriticalMass-0.9.11.pin/game/Hero.cpp
--- CriticalMass-0.9.11/game/Hero.cpp   2004-12-18 05:40:39.000000000 +0300
+++ CriticalMass-0.9.11.pin/game/Hero.cpp   2005-05-26 09:50:59.000000000 +0400
@@ -57,6 +57,8 @@
     _shieldEnergy=30;
     _weaponEnergy=100.0;
     _damageMultiplier = 1.0;
+    _immortal = false;
+    ConfigS::instance()->getBoolean( "HeroImmortal", _immortal);
 
     for( int i=0; i<Hero::MAX_WEAPONS; i++)
     {
@@ -172,6 +174,8 @@
     //hero dead...
     if( _energy <= 0)
     {
+       if (_immortal) _energy=100;
+       else {
    static ParticleGroup *effects =
        ParticleGroupManagerS::instance()->getParticleGroup(EFFECTS_GROUP2);
 
@@ -185,6 +189,7 @@
    }
    _isAlive = false;
     }
+    }
 }
 
 bool Hero::init( void)
diff -urdbN CriticalMass-0.9.11/game/Hero.hpp CriticalMass-0.9.11.pin/game/Hero.hpp
--- CriticalMass-0.9.11/game/Hero.hpp   2004-12-18 05:40:39.000000000 +0300
+++ CriticalMass-0.9.11.pin/game/Hero.hpp   2005-05-26 09:44:51.000000000 +0400
@@ -110,6 +110,7 @@
     float _moveUp;
     float _moveDown;
     bool _isAlive;
+    bool _immortal;
 
     int _energy;
     int _shieldEnergy;
ip1981
()

Суперпатч для PowerManga

Форум — Games

Патч для игрушки PowerManga, слегка исправляющий установку, чтение и запись параметров, но главное — добавляющий режим holiday, в котором бонусы так и сыплются!

diff -urdb powermanga-0.90/Makefile.am powermanga-0.90.pin/Makefile.am
--- powermanga-0.90/Makefile.am 2007-08-13 10:43:21.000000000 +0400
+++ powermanga-0.90.pin/Makefile.am 2009-10-21 00:47:22.000000000 +0400
@@ -2,6 +2,6 @@
 SUBDIRS = texts src graphics graphics/bitmap graphics/bitmap/fonts graphics/sprites graphics/sprites/guardians graphics/sprites/stars graphics/sprites/meteors graphics/sprites/spaceships data data/curves data/levels/curves_phase data/levels/grids_phase sounds sounds/handheld_console
 EXTRA_DIST = bootstrap
 
-pkgdatadir = $(mandir)
+pkgdatadir = $(mandir)/man6
 dist_pkgdata_DATA = powermanga.6
 
diff -urdb powermanga-0.90/src/bonus.c powermanga-0.90.pin/src/bonus.c
--- powermanga-0.90/src/bonus.c 2007-08-24 11:55:16.000000000 +0400
+++ powermanga-0.90.pin/src/bonus.c 2009-10-21 00:47:22.000000000 +0400
@@ -582,6 +582,30 @@
   /* test only
      btype = BONUS_INC_ENERGY;
    */
+
+  if (power_conf->holiday && btype != PENALITY_LONELY_FOE)
+  {
+    switch (rand() % 6)
+    {
+       case 0:
+          btype = BONUS_INC_BY_1;
+          break;
+       case 1:
+          btype = BONUS_INC_BY_2;
+          break;
+       case 2:
+          btype = BONUS_ADD_SATELLITE;
+          break;
+       case 3:
+          btype = BONUS_INC_ENERGY;
+          break;
+       case 4:
+          btype = BONUS_SCR_MULTIPLIER;
+          break;
+       default:
+          break;
+      }
+  }
   return btype;
 }
 
@@ -753,6 +777,30 @@
           btype = PENALITY_LONELY_FOE;
         }
     }
+
+  if (power_conf->holiday && btype != PENALITY_LONELY_FOE)
+  {
+    switch (rand() % 6)
+    {
+       case 0:
+          btype = BONUS_INC_BY_1;
+          break;
+       case 1:
+          btype = BONUS_INC_BY_2;
+          break;
+       case 2:
+          btype = BONUS_ADD_SATELLITE;
+          break;
+       case 3:
+          btype = BONUS_INC_ENERGY;
+          break;
+       case 4:
+          btype = BONUS_SCR_MULTIPLIER;
+          break;
+       default:
+          break;
+      }
+  }
   return btype;
 }
 
diff -urdb powermanga-0.90/src/config_file.c powermanga-0.90.pin/src/config_file.c
--- powermanga-0.90/src/config_file.c   2007-09-02 18:55:29.000000000 +0400
+++ powermanga-0.90.pin/src/config_file.c   2009-10-21 00:48:12.000000000 +0400
@@ -65,6 +65,7 @@
 {
   power_conf->fullscreen = TRUE;
   power_conf->nosound = FALSE;
+  power_conf->holiday = FALSE;
   power_conf->resolution = 640;
   power_conf->verbose = 0;
   power_conf->difficulty = 1;
@@ -244,10 +245,22 @@
     {
       power_conf->nosync = FALSE;
     }
+  if (!lisp_read_bool (lst, "holiday", &power_conf->holiday))
+    {
+      power_conf->holiday = FALSE;
+    }
   if (!lisp_read_int (lst, "verbose", &power_conf->verbose))
     {
       power_conf->verbose = 0;
     }
+  if (!lisp_read_int (lst, "difficulty", &power_conf->difficulty))
+    {
+      power_conf->difficulty = 1;
+    }
+  if (power_conf->difficulty < 0 || power_conf->difficulty > 2)
+    {
+      power_conf->difficulty = 1;
+    }
   if (!lisp_read_int (lst, "scale_x", &power_conf->scale_x))
     {
       power_conf->scale_x = 2;
@@ -289,6 +302,7 @@
            power_conf->fullscreen ? "#t" : "#f");
   fprintf (config, "\t(nosound %s)\n", power_conf->nosound ? "#t" : "#f");
   fprintf (config, "\t(nosync %s)\n", power_conf->nosync ? "#t" : "#f");
+  fprintf (config, "\t(holiday %s)\n", power_conf->holiday ? "#t" : "#f");
 
   fprintf (config, "\n\t;; window size (320 or 640):\n");
   fprintf (config, "\t(resolution  %d)\n", power_conf->resolution);
@@ -303,7 +317,7 @@
   fprintf (config, "\n\t;; difficulty 0 (easy), 1 (normal) or 2 (hard)\n");
   fprintf (config, "\t(difficulty   %d)\n", power_conf->difficulty);
 
-  fprintf (config, "\n\t;; langage en or fr\n");
+  fprintf (config, "\n\t;; language en or fr\n");
   fprintf (config, "\t(lang      ");
   switch (power_conf->lang)
     {
@@ -392,9 +406,13 @@
           fprintf (stdout, "\noptions:\n"
                    "-h, --help     print Help (this message) and exit\n"
                    "--version      print version information and exit\n"
+                   "\n\n"
+                   "These options will be saved to config file:\n"
                    "--320          game run in a 320*200 window (slow machine)\n"
-                   "--2x           scale2x\n"
-                   "--3x           scale3x\n" "--4x           scale4x\n");
+                   "--640          game run in a 640*480 window\n"
+                   "--2x           scale 640*480 by 2x\n"
+                   "--3x           scale 640*480 by 3x\n"
+                   "--4x           scale 640*480 by 4x\n");
 #ifdef POWERMANGA_SDL
           fprintf (stdout,
                    "--window       windowed mode (full screen by default) \n");
@@ -405,8 +423,13 @@
                    "--nosound      force no sound\n"
                    "--sound        force sound\n"
                    "--nosync       disable timer\n"
-                   "--easy         easy bonuses\n"
-                   "--hard         hard bonuses\n"
+                   "--sync         enable timer\n"
+                   "\n"
+                   "--easy         easy game\n"
+                   "--normal       normal game\n"
+                   "--hard         hard game\n"
+                   "--holiday      more bonuses!\n"
+                   "--noholiday    usual game (easy, normal or hard)\n"
                    "--------------------------------------------------------------\n"
                    "keys recognized during the game:\n"
                    "[Ctrl] + [S]   enable/disable the music\n"
@@ -517,12 +540,36 @@
           continue;
         }
 
-      /* difficulty: easy or hard (normal bu default) */
+      /* enable timer */
+      if (!strcmp (arg_values[i], "--sync"))
+        {
+          power_conf->nosync = FALSE;
+          continue;
+        }
+
+      /* more bonuses! */
+      if (!strcmp (arg_values[i], "--holiday"))
+        {
+          power_conf->holiday = TRUE;
+          continue;
+        }
+      if (!strcmp (arg_values[i], "--noholiday"))
+        {
+          power_conf->holiday = FALSE;
+          continue;
+        }
+
+      /* difficulty: easy or hard (normal by default) */
       if (!strcmp (arg_values[i], "--easy"))
         {
           power_conf->difficulty = 0;
           continue;
         }
+      if (!strcmp (arg_values[i], "--normal"))
+        {
+          power_conf->difficulty = 1;
+          continue;
+        }
       if (!strcmp (arg_values[i], "--hard"))
         {
           power_conf->difficulty = 2;
diff -urdb powermanga-0.90/src/config_file.h powermanga-0.90.pin/src/config_file.h
--- powermanga-0.90/src/config_file.h   2007-07-10 00:21:36.000000000 +0400
+++ powermanga-0.90.pin/src/config_file.h   2009-10-21 00:47:22.000000000 +0400
@@ -58,6 +58,8 @@
     Sint32 verbose;
     /** 0 = easy, 1 = normal or 2 = hard */
     Sint32 difficulty;
+    /** More bonuses! */
+    bool holiday;
     /** 0 = EN or 1 = FR */
     Sint32 lang;
   } config_file;
diff -urdb powermanga-0.90/src/Makefile.am powermanga-0.90.pin/src/Makefile.am
--- powermanga-0.90/src/Makefile.am 2007-09-01 00:46:43.000000000 +0400
+++ powermanga-0.90.pin/src/Makefile.am 2009-10-21 00:47:22.000000000 +0400
@@ -1,6 +1,6 @@
 
-gamesdir = $(prefix)/games
-scoredir = /var/games
+gamesdir = $(prefix)/bin
+scoredir = /var/lib/games
 score = powermanga.hi
 
 games_PROGRAMS = powermanga

ip1981
()

Первый замечательный предел :-)

Форум — Talks

Der erste fantastisch Grenzwert

ip1981
()

Webalizer

Форум — Talks

Обновился Webalizer — программа для статистической обработки журналов Apache, Squid, и др. серверов.

В разработке Вебалайзера был перерыв на шесть лет.

В новых версиях:

  • исправлены некоторые проблемы безопасности;
  • добавлено множество параметров настройки (например, обрезание CGI, глубина анализа более 12 месяцев);
  • добавлена проверка страны по IP-адресу (GeoIP);
  • добавлена поддержка сжатых bzip2 файлов;
  • добавлена поддержка форматов W3C;
  • добавлена поддержка IPv6.

Подробности

Перемещено Shaman007 из OpenSource
ip1981
()

Наука vs любовь

Форум — Talks

Фраза "заниматься наукой" имеет такое же отношение к науке, как фраза "заниматься любовью" к любви.

Дискасс!

ip1981
()

Очко в очко

Форум — Talks
ip1981
()

Взятка борзыми щенками

Форум — Talks

http://lenta.ru/news/2009/10/01/limit/

Министерство внутренних дел России предложило ограничить оборот наличных денег в стране для более эффективной борьбы с коррупцией.

Дискасс.

ip1981
()

Первые на Луне

Форум — Talks

http://lenta.ru/news/2009/09/30/lro/

Лунный зонд LRO сфотографировал место высадки американского корабля "Аполлон-11".

ip1981
()

А где теперь есть падонкизатор сайтов?

Форум — Talks

Гуглится только уже мёртвый webox.kiev.ua

ip1981
()

Шателен. «Русские электротехники XIX века»

Форум — Talks
ip1981
()

[По просьбам трудящихся] Newslack

Форум — Development
ip1981
()

Чиновники --- за анониманость в сети

Форум — Talks
ip1981
()

[Slackware] What's new in /etc ?

Форум — Development

Апдейт к www.linux.org.ru/view-message.jsp?msgid=4068051

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import sys
import os
import stat
import glob
import difflib
import string
import subprocess

from PyQt4 import QtGui, QtCore

from pygments import highlight
from pygments.lexers import DiffLexer
from pygments.formatters import HtmlFormatter

CWD = os.getcwd()
EDITOR = 'gvim -f'
PATCH = 'patch -p0'
DIR = '/etc'

def usage():
    print "Usage: %s directory" % sys.argv[0]


# find all *.new files in /etc
def findnew (top = '.', depthfirst = True):
    os.chdir(top)
    names = glob.glob('*.new')
    if not depthfirst:
        yield top, names
    for name in names:
        try:
            st = os.lstat(os.path.join(top, name))
        except os.error:
            continue
        if stat.S_ISDIR(st.st_mode):
            for (newtop, children) in findnew (os.path.join(top, name), depthfirst):
                yield newtop, children
    if depthfirst:
        yield top, names


class MainWindow(QtGui.QWidget):
    newlist = None # QListWidget
    diff    = None # QTextEdit
    edit    = None # QPushButton
    accept  = None # QPushButton
    reject  = None # QPushButton
    patch   = None # QPushButton

    newfile = None # /etc/file.new
    oldfile = None # /etc/file

    @QtCore.pyqtSlot()
    def on_partial_diff(self):
        cursor = self.diff.textCursor()
        start  = cursor.selectionStart()
        end    = cursor.selectionEnd()

        # starting and ending line numbers for the selection
        start_line = self.diff.document().findBlock(start).firstLineNumber()
        end_line   = self.diff.document().findBlock(end).firstLineNumber()

        fulldiff  = self.diff.toPlainText().split('\n');
        max_lines = len(fulldiff) - 1

        # two first lines
        partdiff = fulldiff[0] + '\n' + fulldiff[1] + '\n'
        
        # looking for start of diff block (@@ -16,7 +16,7 @@)
        if start_line < 2:
            start_line = 2
        else:
            while fulldiff[start_line][0:2] != '@@':
                start_line = start_line - 1

        # looking for end of diff block (next @@ ... @@ or EOF)
        if end_line <= start_line:
            end_line = start_line + 1
        
        while end_line < max_lines:
            if fulldiff[end_line][0:2] == '@@':
                break
            end_line = end_line + 1
        
        for l in range(start_line, end_line):
            partdiff = partdiff + fulldiff[l] + '\n'
      
        # apply partial patch
        pipe = subprocess.Popen(PATCH, shell=True, stdin=subprocess.PIPE)
        pipe.stdin.writelines(partdiff)
        pipe.stdin.close()
        
        self.reloaddiff(self.newfile)

    def enable_buttons(self):
        n = self.newlist.count()
        self.edit.setEnabled(n > 0)
        self.accept.setEnabled(n > 0)
        self.reject.setEnabled(n > 0)


    @QtCore.pyqtSlot()
    def on_selection_changed(self):
        self.patch.setEnabled(
                self.diff.textCursor().selectionStart() != self.diff.textCursor().selectionEnd()
                )
        

    @QtCore.pyqtSlot()
    def on_accept(self):
        os.rename(self.newfile, self.oldfile)
        self.newlist.takeItem(self.newlist.currentRow())
        self.enable_buttons()

    @QtCore.pyqtSlot()
    def on_reject(self):
        os.remove(self.newfile)
        self.newlist.takeItem(self.newlist.currentRow())
        self.enable_buttons()

    @QtCore.pyqtSlot()
    def on_edit(self):
        self.accept.setEnabled(False)
        self.newlist.setEnabled(False)

        p = subprocess.Popen(EDITOR + ' ' + self.oldfile, shell=True)
        sts = os.waitpid(p.pid, 0)

        self.reloaddiff(self.newfile)
        self.newlist.setEnabled(True)
        self.accept.setEnabled(True)

    @QtCore.pyqtSlot(QtCore.QString)
    def reloaddiff(self, newfile):
        self.diff.clear()
        self.newfile = str(newfile)
        self.oldfile = self.newfile[0:self.newfile.find('.new')]
        if self.newfile:
            tolines    = open(self.newfile, 'U').readlines()
            fromlines  = open(self.oldfile, 'U').readlines()
            difflines  = difflib.unified_diff(fromlines, tolines, self.oldfile, self.newfile)
            difftext   = string.join(difflines, '')

            self.edit.setToolTip(EDITOR + ' ' + self.oldfile)
            self.reject.setToolTip('Remove ' + self.newfile)
            self.accept.setToolTip(self.newfile + ' -> ' + self.oldfile)
            self.accept.setEnabled(bool(difftext))

            colored_rtf  = highlight(difftext, DiffLexer(), HtmlFormatter(full=True))
            self.diff.setText(colored_rtf)

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        mvbox  = QtGui.QVBoxLayout() # main layout
        split  = QtGui.QSplitter(QtCore.Qt.Horizontal, self) # left-right splitter
        
        rpart  = QtGui.QWidget(split) # right side
        lpart  = QtGui.QWidget(split) # left side

        rvbox  = QtGui.QVBoxLayout() # right side layout
        lvbox  = QtGui.QVBoxLayout() # left side layout
        rpart.setLayout(rvbox)
        lpart.setLayout(lvbox)

        self.diff = QtGui.QTextEdit() # to show diff
        self.diff.setReadOnly(True)
       
        self.newlist = QtGui.QListWidget() # to show all *.new files
       # Load all *.new files  
        for (basepath, children) in findnew(DIR):
            for child in children:
                self.newlist.addItem(os.path.join(basepath, child))
        os.chdir(CWD)
        
        quit        = QtGui.QPushButton('&Quit', self)
        self.accept = QtGui.QPushButton('&Accept', self)
        self.reject = QtGui.QPushButton('&Reject', self)
        self.edit   = QtGui.QPushButton('&Edit old...', self)
        self.patch  = QtGui.QPushButton('A&pply selection', self)
        self.patch.setEnabled(False)
        self.patch.setToolTip('Patch using block with selected text')

        lvbox.addWidget(self.diff) # diff is on the left side
        lvbox.addWidget(self.patch) # "apply patch" button (can be invisible)
        buttons = QtGui.QHBoxLayout() # buttons are below it
        lvbox.addLayout(buttons) # buttons layout
        buttons.addWidget(self.accept)
        buttons.addWidget(self.reject)
        buttons.addWidget(self.edit)

        rvbox.addWidget(self.newlist) # file list is on the right side
        rvbox.addWidget(quit) # quit button is below it

        mvbox.addWidget(split) # split is the main widget of main window
        split.addWidget(lpart) # add the left side on the split
        split.addWidget(rpart) # add the right side on the split

        self.resize(640, 480)
        self.setWindowTitle("What\'s new in %s ?" % DIR)
        self.setLayout(mvbox)

        self.connect(quit, QtCore.SIGNAL('clicked()'), QtGui.qApp, QtCore.SLOT('quit()'))
        self.connect(self.edit, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT('on_edit()'))
        self.connect(self.accept, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT('on_accept()'))
        self.connect(self.reject, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT('on_reject()'))
        self.connect(self.diff, QtCore.SIGNAL('selectionChanged()'), self, QtCore.SLOT('on_selection_changed()'))
        self.connect(self.newlist, QtCore.SIGNAL('currentTextChanged(QString)'),
                             self, QtCore.SLOT('reloaddiff(QString)'))
        
        self.newlist.setCurrentRow(0)
        self.enable_buttons()


if len(sys.argv) > 2:
    usage()
    sys.exit(1)
elif len(sys.argv) == 2:
    DIR = sys.argv[1]


app = QtGui.QApplication(sys.argv)
win = MainWindow()
win.show()

sys.exit(app.exec_())

 

ip1981
()

[Суррогаты]

Форум — Talks

Интересно, почему у Брюса Уиллиса моск не вскипел.

:-)

ip1981
()

Стерлитамакская государственная педагогическая академия ЖЖОТ!

Форум — Talks
ip1981
()

[Slackware] What's new in /etc ?

Форум — Development

После обновления Слаки с директории /etc остаётся несколько файлов типа rc.inet1.new, которые по идее должны заменить старые файлы (типа rc.inet1).

Я обысно это делал руками: diff -u rc.inet1 rc.inet1.new, а затем принимал решение о замене. мне это надоело, и я написал программу на Питоне, которая это автоматизирует. Программа графическая, использует Qt4, pygments.

http://picasaweb.google.ru/lh/photo/EVmsIvYlCcb-ZmFgkTSdNQ?feat=directlink

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import sys
import os
import stat
import glob
import difflib
import string
from PyQt4 import QtGui, QtCore
from pygments import highlight
from pygments.lexers import DiffLexer
from pygments.formatters import HtmlFormatter

editor = 'gvim -f'

# find all *.new files in /etc
def findnew (top = '/etc', depthfirst = True):
    os.chdir(top)
    names = glob.glob('*.new')
    if not depthfirst:
        yield top, names
    for name in names:
        try:
            st = os.lstat(os.path.join(top, name))
        except os.error:
            continue
        if stat.S_ISDIR(st.st_mode):
            for (newtop, children) in findnew (os.path.join(top, name), depthfirst):
                yield newtop, children
    if depthfirst:
        yield top, names


class MainWindow(QtGui.QWidget):
    newlist = None # QListWidget
    diff    = None # QTextEdit
    edit    = None # QPushButton
    accept  = None # QPushButton
    reject  = None # QPushButton

    newfile = None # /etc/file.new
    oldfile = None # /etc/file

    def enable_buttons(self):
        n = self.newlist.count()
        self.edit.setEnabled(n > 0)
        self.accept.setEnabled(n > 0)
        self.reject.setEnabled(n > 0)


    @QtCore.pyqtSlot()
    def on_accept(self):
        os.rename(self.newfile, self.oldfile)
        self.newlist.takeItem(self.newlist.currentRow())
        self.enable_buttons()

    @QtCore.pyqtSlot()
    def on_reject(self):
        os.remove(self.newfile)
        self.newlist.takeItem(self.newlist.currentRow())
        self.enable_buttons()

    @QtCore.pyqtSlot()
    def on_edit(self):
        self.accept.setEnabled(False)
        self.newlist.setEnabled(False)
        
        os.system(editor + ' ' + self.oldfile)
        
        self.reloaddiff(self.newfile)
        self.newlist.setEnabled(True)
        self.accept.setEnabled(True)

    @QtCore.pyqtSlot(QtCore.QString)
    def reloaddiff(self, newfile):
        self.diff.clear()
        self.newfile = str(newfile)
        self.oldfile = self.newfile[0:self.newfile.find('.new')]
        if self.newfile:
            tolines      = open(self.newfile, 'U').readlines()
            fromlines    = open(self.oldfile, 'U').readlines()
            difflines    = difflib.unified_diff(fromlines, tolines, self.oldfile, self.newfile)
            difftext = string.join(difflines, '')

            self.edit.setToolTip(editor + ' ' + self.oldfile)
            self.reject.setToolTip('Remove ' + self.newfile)
            self.accept.setToolTip(self.newfile + ' -> ' + self.oldfile)
            self.accept.setEnabled(bool(difftext))

            colored_rtf  = highlight(difftext,
                            DiffLexer(),
                            HtmlFormatter(full=True))
            self.diff.setText(colored_rtf)

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        mvbox  = QtGui.QVBoxLayout() # main layout
        split  = QtGui.QSplitter(QtCore.Qt.Horizontal, self) # left-right splitter
        
        rpart  = QtGui.QWidget(split) # right side
        lpart  = QtGui.QWidget(split) # left side

        rvbox  = QtGui.QVBoxLayout() # right side layout
        lvbox  = QtGui.QVBoxLayout() # left side layout
        rpart.setLayout(rvbox)
        lpart.setLayout(lvbox)

        self.diff = QtGui.QTextEdit() # to show diff
        self.diff.setReadOnly(True)
      
        self.newlist = QtGui.QListWidget() # to show all *.new files
       # Load all *.new files  
        for (basepath, children) in findnew():
            for child in children:
                self.newlist.addItem(os.path.join(basepath, child))
        
        quit        = QtGui.QPushButton('&Quit', self)
        self.accept = QtGui.QPushButton('&Accept', self)
        self.reject = QtGui.QPushButton('&Reject', self)
        self.edit   = QtGui.QPushButton('&Edit old...', self)

        lvbox.addWidget(self.diff) # diff is on the left side
        buttons = QtGui.QHBoxLayout() # buttons are below it
        lvbox.addLayout(buttons) # buttons layout
        buttons.addWidget(self.accept)
        buttons.addWidget(self.reject)
        buttons.addWidget(self.edit)

        rvbox.addWidget(self.newlist) # file list is on the right side
        rvbox.addWidget(quit) # quit button is below it

        mvbox.addWidget(split) # split is the main widget of main window
        split.addWidget(lpart) # add the left side on the split
        split.addWidget(rpart) # add the right side on the split

        self.resize(640, 480)
        self.setWindowTitle('What\'s new in /etc ?')
        self.setLayout(mvbox)

        self.connect(quit, QtCore.SIGNAL('clicked()'), QtGui.qApp, QtCore.SLOT('quit()'))
        self.connect(self.edit, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT('on_edit()'))
        self.connect(self.accept, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT('on_accept()'))
        self.connect(self.reject, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT('on_reject()'))
        self.connect(self.newlist, QtCore.SIGNAL('currentTextChanged(QString)'),
                             self, QtCore.SLOT('reloaddiff(QString)'))
        
        self.newlist.setCurrentRow(0)
        self.enable_buttons()



app = QtGui.QApplication(sys.argv)
win = MainWindow()
win.show()

sys.exit(app.exec_())

 

ip1981
()

Информационные технологии в России

Форум — Talks
ip1981
()

Ещё один jabber-shell

Форум — Development

Идея витает в воздухе давно, есть несколько реализаций разной степени запущенности. Большинство использует Net::XMPP и Net::Jabber и имеют проблемы.

Этот скрипт использует AnyEvent::XMPP и основан на примере в исходниках оного. Работает.

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;
use utf8;
use locale;
use open qw( :utf8 :std );
use Getopt::Long qw(:config bundling);
use AnyEvent;
use AnyEvent::XMPP::Client;
use AnyEvent::XMPP::Ext::Disco;
use AnyEvent::XMPP::Ext::Version;
use AnyEvent::XMPP::Namespaces qw/xmpp_ns/;


my $SCRIPT = $0;
my $VERSION = '0.1';
my $PORT = '5222';
my $PASSWORD = '';
my @ADMINS = ();
my $JID = '';
my $DEBUG = 0;
my $TLS = 1;
my $HTTP = 0;

sub usage
{
    print <<USAGE;
Jabber shell v$VERSION: shell robot to execute commands via jabber

Usage: $SCRIPT [options]


Options (default in brackets):
    --jid,      -j  jabber ID, e. g. 'name\@jabber.org' or 'name\@jabber.org/resource'
    --password, -w  password for the account ($PASSWORD)
    --port,     -p  port to connect ($PORT)

    --admin,    -a  authorized accounts to execute commands from (@ADMINS)

    --[no]debug     turn debug on/off ($DEBUG)

    --help,     -h  this help message


Examples:

$SCRIPT -j solo\@jabber.ru/home -w qwerty --admin buck\@jabber.org

USAGE

    exit (0);
}

GetOptions(
    'port|p=i'       => \$PORT,
    'password|passwd|w=s'   => \$PASSWORD,
    'admin|a=s'      => \@ADMINS,
    'debug|d!'       => \$DEBUG,
    'jid|jabber|j=s' => \$JID,
    'help|h'         => sub {usage}
);

unless ($JID)
{
    usage();
}


my $j       = AnyEvent->condvar;
my $cl      = AnyEvent::XMPP::Client->new (debug => $DEBUG);
my $disco   = AnyEvent::XMPP::Ext::Disco->new;
my $version = AnyEvent::XMPP::Ext::Version->new;

$cl->add_extension ($disco);
$cl->add_extension ($version);

$cl->set_presence (undef, "Jabber shell bot v$VERSION", 1);

$cl->add_account ($JID, $PASSWORD);
warn "connecting to $JID...\n";

$cl->reg_cb (
   session_ready => sub {
      my ($cl, $acc) = @_;
      warn "connected!\n";
   },
   contact_request_subscribe => sub {
      my ($cl, $acc, $roster, $contact) = @_;
      $contact->send_subscribed;
      warn 'Subscribed to ' . $contact->jid . "\n";
   },
   error => sub {
      my ($cl, $acc, $error) = @_;
      warn 'Error encountered: ' . $error->string . "\n";
      $j->broadcast;
   },
   disconnect => sub {
      warn "Got disconnected: [@_]\n";
      $j->broadcast;
   },
   message => sub {
      my ($cl, $acc, $msg) = @_;
      return unless $msg;
      my $cmd = $msg->any_body;
      my $adm = $msg->from;

      warn "# $adm -> $cmd:\n";

      my $repl = $msg->make_reply;

      if ($adm ~~ @ADMINS)
      {
          my $out = '';
          if ($cmd =~ s/^\s*cd\s+//)
          {
             $out = chdir($cmd) ? `pwd` : 'Failed'
          } else
          {
              $out = `$cmd 2>&1`
          }
          if ($out)
          {
            warn $out;
            $repl->add_body($out);
          }
      } else
      {
          warn "Forbidden.\n";
          $repl->add_body('Forbidden');
      }

      $repl->send;
   },
);

$cl->start;

$j->wait;

exit(0);
ip1981
()

RSS подписка на новые темы