کنترل MPlayer به وسیله کلیدهای لپ‌تاپ

مدتی پیش، میخواستم راهی برای کنترل MPlayer از گوشیم پیدا بکنم. نتونستم با MPDها کنار بیام و بالاخره، آستین‌ها رو بالا زدم تا خودم کاری بکنم! ولی فعلا درمورد اون نمینویسم. در این بین فهمیدم چطور میشه ام‌پلیر رو از دور (منظور جایی غیر از خود ام‌پلیر) کنترل کرد و به فکرم افتاد از شرتکات‌های کنترل پلیر لپ‌تاپم هم استفاده‌ای بکنم. برای VLC و بقیه پلیرها احتمالا چیز آنچنانی نیست و اگه با MPDها راحت بودم، واسه ام‌پلیر هم میتونستم خیلی آسون‌تر کاری بکنم. ولی فعلا اون‌ها رو میذارم کنار.

ام‌پلیر میتونه به وسیله فایل‌های پایپ کنترل بشه. من برای فایل‌های پایپم، یه دایرکتوری مخصوص به آدرس ‎/media/fifo دارم. اونجا یه فایل فیفو به اسم mplfifo درست میکنم:

mkfifo /media/fifo/mplfifo

الان باید شرتکات‌ها رو روی اوپن‌باکس تنظیم بکنم. احتمالا میدونین که هر کلیدی روی صفحه کلیدتون یه کدی داره. مثلا k همون k هست. ولی بعضی وقت‌ها اینقدر ساده نیست. مثلا کد کپس‌لاک من ISO_Next_Group هست! کلیدهای کنترل پلیر هم از این نوع هستن.

برای پیدا کردن این کدها، یه راه ساده‌ای وجود داره. میتونین از برنامه xev که داخل خود X هست استفاده بکنین. اگه میخواین مستقیم به کد کلید برسین، میتونین از این تکه کد کوچیک استفاده بکنین:

xev | grep -oP "keycode \S* \(keysym \S*?, \S*?\)" | cut -d, -f2 | tr -d \) | tr -d " "

کلیدهایی که میخواین رو بزنین و بعد پنجره رو ببندین (کل کد رو با Ctrl+C قطع نکنین!). کدهای کلیدهای کنترل پلیر من اینا هستن:

XF86AudioPlay
XF86AudioStop
XF86AudioNext
XF86AudioPrev

حالا شرتکات‌ها رو میسازیم. باید دستور رو به فایل پایپ بفرستیم. مثلا برای توقف و اجرای پلیر، از این خط میشه استفاده کرد:

echo pause > /media/fifo/mplfifo

اگه برای احرای شرتکات‌ها از bash (یا شل دیگه‌ای که از «<» پشتیبانی بکنه) استفاده نشه، مجبوریم خودمون بدیمش به بش:

bash -c 'echo pause > /media/fifo/mplfifo'

دستوراتی که من استفاده میکنم، pause،‏ stop،‏ pt_step 1 و pt_step -1 هستن. لیست کامل دستورات رو میتونین از اینجا ببینین. برای مثال، شرتکات‌های من توی اوپن‌باکس به این صورت هستن:

<keybind key="XF86AudioPlay">
  <action name="Execute">
    <execute>bash -c 'echo pause > /media/fifo/mplfifo'</execute>
  </action>
</keybind>
<keybind key="XF86AudioStop">
  <action name="Execute">
    <execute>bash -c 'echo stop > /media/fifo/mplfifo'</execute>
  </action>
</keybind>
<keybind key="XF86AudioNext">
  <action name="Execute">
    <execute>bash -c 'echo pt_step 1 > /media/fifo/mplfifo'</execute>
  </action>
</keybind>
<keybind key="XF86AudioPrev">
  <action name="Execute">
    <execute>bash -c 'echo pt_step -1 > /media/fifo/mplfifo'</execute>
  </action>
</keybind>

خوب، حالا نوبت خود ام‌پلیر هست. من همیشه نمیخوام از این شرتکات‌ها استفاده بکنم. مثلا موقع دیدن فیلم لازمم نمیشه و اگه آهنگی اونجا pause شده باشه، با اون قاطی میشه. پس یه alias جداگانه براش میسازم:

alias mpls='mplayer -input file=/media/fifo/mplfifo'

اینو میذارم توی zshrcم. الان میتونم آهنگ‌ها رو با mpls و فیلم‌ها رو با mplayer ببینم. از همین فایل پایپ برای کنترل ام‌پلیر از یه صفحه وب، که سرورش کامپیوتر خودمه، و البته فقط با شبکه‌ای که لپتاپم وصله میشه دیدش، استفاده میکنم.

حل مشکلی اساسی به وسیله پایتون: انگلیسی بودن کیبورد حین تایپ فارسی

خیلی اتفاق افتاده که موقع چت با کسی، اون بخواد فارسی تایپ کنه، ولی کیبوردش انگلیسی باشه و نفهمه و مسیج انگلیسی بیاد. مثلا sghl. خوشبختانه برای خود من همچین مشکلی پیش نمیاد زیاد، چون همیشه چشمام روی اسکرین هست. ولی وقتی کس دیگه‌ای مینویسه، به خصوص موقع چت، زیاده اتفاق میفته. خوب، قرار نیست که هر دفعه صبر کنم اون دوباره بنویسه یا با تبدیل حروف تو ذهنم اون رو رمز گشایی بکنم! پس... ایمکس، بیا بالا ;)

یه اسکریپت کوچیک پایتون مینویسم که از یه فایل اون حروف عجق وجق انگلیسی رو بگیره:

#! /usr/bin/python2
# -*- coding: utf-8 -*-

import sys

def main():
    per = ["ض", "ص", "ث",  "ق",  "ف",  "غ",  "ع",  "ه",  "خ",  "ح",  "ج",  "چ",  "ش",  "س",  "ی",  "ب",
        "ل",  "ا",  "ت",  "ن",  "م",  "ک",  "گ",  "ظ",  "ط",  "ز",  "ر",  "ذ",  "د",  "پ",  "و"]
    eng = ["q",  "w",  "e",  "r",  "t",  "y",  "u",  "i",  "o",  "p",  "[",  "]",  "a",  "s",  "d",
        "f",  "g",  "h",  "j",  "k",  "l",  ";",  "'",  "z",  "x",  "c",  "v",  "b",  "n",  "m",  ","]
    s = ""
    for i in open(sys.argv[1]).readlines():
        s = s + i
    for i in range(len(per)):
        s = s.replace(eng[i], per[i])
    print(s)

if __name__ == '__main__':
    main()

چیزی برای توضیح دادن نداره. اول دو تا آرایه از حروف روی کیبورد به دو زبان فارسی و انگلیسی میگیره (که احتمالا راه بهتری هم وجود داره)، بعد فایل رو میخونه، حروف رو جایگزین میکنه و بعد پرینت. ورژن دو بودن پایتون هم به این خاطره که این ورژن پشتیبانی بهتری از UTF-8 و کاراکترهای فارسی داره.

این اسکریپت کارش رو میکنه، ولی باید هر دفعه بذارمش به یه فایل و بعد بزنم پنجره ترمینال بیاد و کد بزنم و ... . درسته، میشه به جای فایل از STDIN استفاده کنم، ولی فکر بهتری دارم. اسکریپت رو کمی تغییر میدم:

#! /usr/bin/python2
# -*- coding: utf-8 -*-

import sys
import os
import commands as cm

def main():
    per = ["ض", "ص", "ث",  "ق",  "ف",  "غ",  "ع",  "ه",  "خ",  "ح",  "ج",  "چ",  "ش",  "س",  "ی",
        "ب",  "ل",  "ا",  "ت",  "ن",  "م",  "ک",  "گ",  "ظ",  "ط",  "ز",  "ر",  "ذ",  "د",  "پ",  "و"]
    eng = ["q",  "w",  "e",  "r",  "t",  "y",  "u",  "i",  "o",  "p",  "[",  "]",  "a",  "s",  "d",
        "f",  "g",  "h",  "j",  "k",  "l",  ";",  "'",  "z",  "x",  "c",  "v",  "b",  "n",  "m",  ","]
    s = cm.getoutput("xclip -selection clipboard -o")
    for i in range(len(per)):
        s = s.replace(eng[i], per[i])
    os.system("echo -n \"" + s + "\" | xclip -selection clipboard")

if __name__ == '__main__':
    main()

دو تا جا عوض شده: اول این که به جای فایل، ورودی رو از کلیپ‌بورد میگیره. و دومی هم این که خروجی رو به کلیپ‌بورد میده!

الان بهتر شد، و کافیه هر دفعه متن رو کپی و این اسکریپت رو از ترمینال اجرا کنم. ولی یه شرتکات هم میذارم که دیگه سنگ تموم بذارم ‎:D مثلا Ctrl+Alt+C گزینه خوبیه

البته این آرایه فقط حروف اصلی روی کیبورد رو داره، و مثلا «آ» یا «،» رو نداره و اگه طرف ویندوزی باشه، «و» و «پ» میرن یه جای دیگه. ولی خوب، اونجاهاش رو خودم میفهمم دیگه :)

مهاجرت به وبلاگ ایستا

مدتی بود که می‌خواستم از شر فیلتر بودن وبلاگم خلاص بشم (نه به خاطر خواننده‌ها، که به خاطر خودم ‎:D)، ولی هیچ سرویس وبلاگ داینامیکی راضیم نمیکرد و قرار هم نبود هاست بخرم. ولی بعد، شاهین به سرویس وبلاگ استاتیکی کوچ کرد و من فهمیدم این بهترین راهه. شاهین از نیکولا استفاده کرده بود، ولی من فکر کردم شاید چیز بهتری هم باشه. کلی سیستم بلاگینگ استاتیک امتحان کردم، از جمله Octopress،‏ Pelican،‏ Blosxom و ... . ولی غیر از نیکولا و پلیکان، تغریبا هیچکدوم از UTF-8 پشتیبانی درست حسابی نمیکردن و فقط برای انگلیسی و زبان‌هایی که فقط از حروف انگلیسی استفاده میکنن، مناسب بودن. پلیکان هم برای خودش دردسری داشت. پس رفتم سراغ همون نیکولا.

چیز زیادی برای گفتن نیست. غیر از اینکه من طراح وبسایت نیستم و به غیر از عوض کردن چند تا کد کوچیک CSS و HTML، کار زیادی از دستم بر نمیومد. واسه همین قالبم فوق‌العاده نیست و زشته هنوز. ولی خوب، کار میکنه و قابل تحمله.

پست‌های قبلیم یه سری مشکلاتی دارن که بزرگترینشون آدرسشونه. شاید حوصله بکنم بشینم آدرس همه پنجاه و پنج پست قبلیم رو درست کنم، ولی فعلا از این خبرا نیست. ;) تصاویری که روی وردپرس آپلود کرده بودم هم فیلترن و جای دیگه‌ای آپلودشون نکردم هنوز.

بعد از قابل استفاده شدن وبلاگ، رفتم تو گیت‌هاب یه صفحه براش بسازم. ولی alinuxgeek گرفته شده بود. پس آدرس جدید وبلاگ straygeek.github.io هست :)

شرتکات فوکوس روی پنجره ایمکس

خوب، امروز پست شاهین در مورد استفاده از ایمکس به عنوان ترمینال رو دیدم. یه مدت خودم هم این فکر رو تو سرم داشتم، ولی تنبلی نمیذاره کاری بکنیم ;)‏

خوب، این پست رو میخونم. همه جا تا multi-term خوب و خوش پیش میره. ولی وقتی به تنظیمات i3 میرسم، یه چیز جالب یادم میفته: دسکتاپ من i3 نیست! چاره چیه؟

باید پنجره ایمکس رو طوری بکنم که با یه شرتکات بیاد و بره. اوپن باکس به هیچ وجه تو مدیریت پنجره‌ها از طریق خط فرمان خوب نیست. پس باید یه راه دیگه پیدا کنم. با یه سرچ، به یه ابزار داخلی X میرسم: xdotool. کمی تو راهنماش میچرخم و چیزهایی رو که لازم هستن پیدا میکنم. چیزایی مثل مینیمایز کردن، بالا آوردن و گرفتن آی‌دی پنجره. خوب، فقط مونده این‌ها رو ترکیب بکنیم. یه اسکریپت کوتاه می‌نویسیم:

‎#! /bin/bash

id="$(xdotool search --name --limit 1 emacs@$HOST)"‎
active="$(xdotool getactivewindow)"‎

if [ "$id" = "" ]; then
zenity --error --title "Error" --text "No emacs is running\!"‎
exit 1
fi

if [ $id != "$active" ]; then
xdotool windowmap $id
xdotool windowfocus $id
else
xdotool windowminimize $id
fi

اول بگم که اگه بخواین این رو کپی کنین، یه سری کاراکتر برای درست نشون دادن این کد گذاشتم. پس اگه بخواین کپیش کنین، اول چک کنین ببینین کاراکتر اضافی دارین یا نه.
خوب، میشه گفت هرکسی با یه نگاه میتونه بگه این اسکریپت چیکار میکنه. ولی به هر حال توضیح میدم. اولین سطر که میگیم با بش اجرا کن. بعد، آی‌دی پنجره‌ای رو که اسمش emacs@HOSTNAME هست، میگیرم (HOSTNAME همون اسم کامپیوتره منه) که همون پنجره ایمکسه و میذارم تو متغیر id. بعد، آی‌دی پنجره فعال رو میگیرم و اونو هم میندازم تو متغیر active. حالا چک میکنم ببینم اصلا پنجره ایمکسی هست یا نه. اگه نباشه با zenity یه ارور میدم و میزنم بیرون. حالا یه if دیگه میذارم که ببینم پنجره فعال همون ایمکسه یا نه. اگه باشه، مینیمایزش میکنم و اگه نباشه، میارمش بالا و روش فوکوس میکنم.
خوب، حالا این رو تو یه فایل میریزم و یه شرتکات دلخواه براش تعیین میکنم و تمام.
ولی من شخصا زیاد از ترمینال ایمکس خوشم نیومد. بعضی شرتکات‌ها رو ساپورت نمیکنه (که نباید هم بکنه. به هر حال شرتکات‌های خودشه دیگه!) و بعضی کارهای دیگه هم نمیشن.
ولی به هر حال این کد رو نگه میدارم تا شاید یه روز برای برنامه دیگه‌ای، مثل GoldenDict، ازش استفاده بکنم ;)

یه گیگ‌بازی کوچولو: دانلود ده تا فایل پی‌دی‌اف از «ستاد سلام »

دیروز، کسی از گوگل پلاس، که یادم نیست کی بود، این لینک رو از ستاد سلام شیر کرده بود. درمورد چیزایی مثل حقوق زنان هست. می‌خواستم تمام فایل‌های پی‌دی‌اف رو دانلود بکنم، ولی در شأن یه گیک نیست که تک به تک بشینه فایل‌ها رو دانلود بکنه ;) پس یکی دو خط کد می‌زنیم.
اول، باید یه فایل اچ‌تی‌ام‌ال از اون صفحه ستاد سلام بگیرم:

wget "http://www.setadsalam.net/paper-tools/trakt-nevisi" -O trakt_nevisi.html

حالا، باید لینک‌ها رو از فایل جدا کنیم و بذاریم تو یه فایل دیگه:

cat trakt_nevisi.html | grep -Po 'href="(.*?)\.pdf"' | cut -d\" -f2 | uniq | sed "s|^|http://www.setadsalam.net|g" | tee URLs

خلاصه این کد اینه که اول با grep و cut آدرس‌ها رو از فایل جدا می‌کنیم، بعد چون هر آدرس یه بار هم تکرار شده، تکراری‌ها رو حذف می‌کنیم و بعد، به خاطر این که اولشون اسلش (/) هست و نه آدرس سایت، آدرس ستاد سلام رو هم به اولش اضافه می‌کنیم. بعدش هم با tee آدرس‌ها رو تو فایل URLs میذاریم.
خوب، حالا فقط دانلودشون مونده:

wget -i URLs

با آپشن ‎-i به wget میفهمونیم که باید آدرس‌ها رو از فایل URLs بگیره.
حالا برای اطمینان، تعداد فایل‌ها رو بررسی می‌کنیم:

‎ $ ls *.pdf | wc -l
‎10

خوب، ده تا کلیک صرفه‌جویی شد ;)

پی‌نوشت: این پست و پست قبلی رو با ایمیل به وردپرس فرستادم. واسه همین تا وقتی که بتونم سد فیلترینگ رو رد بکنم، این دو مطلب و شاید مطالب بعدی رو به دسته خاصی نمی‌تونم اضافه بکنم.