openwrt و اضافه کردن یک پکیج جدید

اینم یه تجربه پراکنده!

توی پست قبل من OpenWrt رو معرفی کردم. بعد از یه مدت متوجه شدم که یه پروژه جدید به نام LEDE ایجاد شده که انگار همونه و الان حدود ۲ سال هست که OpenWrt زیاد بروزرسانی نمی‌شه. حالا با توجه به علاقه‌ام به کارهای نزدیک سخت‌افزار و مسائل مرتبط به cross compile سعی کردم که کل OpenWrt رو کامپایل کنم و سعی کنم یه پکیج جدید بهش اضافه کنم.

البته پکیجی که من دنبالش بودم tun2socks بود که پکیجش بصورت غیر رسمی وجود داشت. کاری که من کردم این بود که آدرس‌ها رو عوض کردم و یادگرفتم که چطور میتونم اون رو برای روترم کامپایل کنم. نتیجه کار من رو میتونید توی گیت‌هاب من پیدا کنید

روند کار به ترتیب اینجوریه که:

  1. اول سورس کد رو با گیت از گیت‌هاب میگیرید
  2. دوم با توجه به راهنمای آنلاین تمام پکیج‌ها رو دانلود میکنید
  3. پکیج رو اضافه می‌کنید
  4. با استفاده از نوع معماری سیستم و نوع دستگاه و پکیج‌ها رو انتخاب می‌کنید
  5. و از ابتدا کامپایلر و کل لینوکس و پکیج رو کامپایل میکنید

پینشهاد میکنم که برای شروع اینها بخونید:

امیدوارم به دردتون خورده باشه!

همین!

غواصی در اعماق: malloc، پروسه‌ها و حافظه تخصیص یافته

اینم یه تجربه پراکنده دیگه!

چند شب پیش یکی از دوستان با این سوال به سراغ من اومد:

مشکل اینه که وقتی با malloc یا new یک حافظه تخصیص میدی و با free یا delete حافظه رو برمیگیردونی, اون حافظه شاید بلاک هاش خالی بشه اما توی تسک لیست خالی به عنوان منابع استفاده شده میاره و تا پایان پروسه پاک نمیشه. از دوستانی که آشنایی دارن پیگیری کن ببین جریان چیه. مهمه .

خدا خیرت بده. یه جایی از حافظه نمایی رشد میکه و وقتی خالیش میکنیم (با اینکه از لیست heap سیستم عامل خالی میشه) اما توی لیست پروسه‌ها(مثل نتیجه ps) هنوز به عنوان حافظه استفاده شده هست و حافظه آزاد نمیشه !!!‌ عجیبه . کلی توی اینترنت اینو سوال کردن !!

من که لینوکسم. اما فکر کنم ویندوزم همینه. چون سوالای اینترنت هردوشونه

کلا بخوام سوال رو خلاصه کنم اینجوریه که چرا وقتی حافظه رو به سیستم‌عامل پس میدیم واقعا پس داده نمیشه. من یکم از دانسته‌هام استفاده کردم و یکم هم تحقیقات کردم

پیش‌نیازها

پیش نیازهایی که به نظرم باید بدونیم ایناست:

  • نکته صفر اینکه با توجه به تحقیقات من زیر کلمه کلیدی new از همون malloc استفاده میشه. پس بررسی malloc به تنهایی میتونه جوابی برای ما فراهم کنه.
  • اول اینکه باید بدونیم که وقتی malloc صدا زده میشه چه اتفاقی میفته. کاری که malloc میکنه اینه که heap پروسه رو بهت اختصاص میده. حالا heap توسط سیستم عامل مدیریت میشه و در صورت نیاز به پروسه‌ی شما حافظه بیشتری تخصیص میده.
  • دوم اینکه فضای heap توسط کرنل مدیریت میشه و به اصطلاح نگاشته میشه به یه چیزی به نام Virtual Memory
  • سوم اینکهVirtual Memory نگاشته میشن به چیزی به نام Memory Page که نزدیک به سخت افزار تره
  • چهارم اینکه Memory Page نگاشته میشن بلوک‌های واقعی حافظه. از این مطمئن نیستم اما این نزدکترین لایه به سخت افزاره که من باهاش آشنا هستم.

بررسی مساله

حالا اگه بخوایم مساله رو بررسی کنیم باید به چند‌تا سوال جواب بدیم:

  • اول اینکه malloc چطور عمل میکنه؟ در پیاده‌سازیش ساز و کارش چیه؟
  • دوم اینکه روند افزایش طول Virtual Memory و اضافه شدن Memory Pageها چطوره؟
  • سوم اینکه بعد از پس دادن Memory Pageها سیستم عامل چطور اونها رو از یک پروسه پس میگیره؟

خب جواب سوالا به ترتیب اینا به نظر میرسن:

  • پیاده‌سازی‌های متفاوتی از malloc وجود داره
    • پیاده‌سازی معمولا اون اینطوریه که پس از گرفتن حافظه وقتی free شد معمولا اونها رو به سیستم عامل پس نمیده و نگه میداره که شاید بعدا بخواد دوباره تخصیص بده.
    • دوم اینکه درخواست یک Memory Page جدید توسط دستوراتی مثل mmap و sbrk درخواست یک بلاک بزرگ حافظه میکنه و اون رو بنا به درخواست نرم‌افزار تخصیص میده.
    • بعدش هم اینکه برای اینکه یک Memory Page رو برگردونه به سیستم عامل بایستی تمام حافظه‌هایی که روی اون تخصیص داده شدن برگشت داده بشه. که این هم همیشه اتفاق نمی‌افته.
    • معمولا هم پیاده‌سازی‌ها اینجورین که حافظه‌ای که توسط sbrk افزایش پیدا کرده رو دست نمیزنن(دلیل دقیقش رو نمیدونم) و حافظه‌ای که توسط mmap اضافه شده رو به راحتی برمیگردونن.
  • تقریبا جواب سوال دوم رو هم تا الان دادم. مقدار Virtual Memory توسط glibc کنترل میشه و بوسیله malloc تخصیص داده میشه.
  • جواب سوال سوم هم اینه که کرنل لینوکس همیشه حافظه برگشت داده شده رو برنمیگردونه چون که هزینه داره فقط اون رو علامت میزنه که در صورت نیاز اون رو حذف کنه یا به swap ببره.

راه حل مساله

حالا بریم سراغ مساله اصلی(چرا حافظه برگشت داده شده برگشت نخورده) و توجیهی که براش پیدا کردیم:
* مهمترین دلیل این اتفاق به نظرم malloc هست که حافظه رو نگه داشته و برنگردونده
* دومین دلیلش هم میتونه این باشه که کرنل هنوز Memory Page رو برنداشته و فقط علامت زده

حالا راه حل چیه:
* اول اینکه به کرنل و glibc اعتماد کنیم
* دوم اینکه بیایم و این پارامتر مروبط به malloc رو تنظیم کنیم۴
* سوم اینکه بیایم از یه پیاده‌سازی دیگه برای تخصیص حافظه و آزاد سازی اون استفاده کنیم
* چهارم اینکه بیایم خودمون مستقم از mmap و munmap استفاده کنیم

امیدوارم اینا راه گشای دیگران هم باشه

برای مطالعه بیشتر:

۱

۲

۳

۴

همین!

لذت برنامه نویسی: makefile همه منظوره

اینم یه تجربه پراکنده دیگه!

من قبلا هم در مورد ابزارهایی مثل makefile و cmake که کامپیال کردن نرم‌افزارها بالاخص در زبان‌های C/C++ رو راحت می‌کنن نوشتم. البته باید بگم که هیچوقت بصورت کامل و درستی یاد نگرفتم که makefile چطوره و چطور میشه باهاش سرو کله زد تا اینکه در یکی از پروژه‌ها مجبور به استفاده از makefile شدم و با کمک یکی از دوستان یه پروژه متن‌باز پیدا کرد که یه مدل آماده makefile که توش تقریبا همه کارهای معمول انجام شده بود رو آورده بود.

توی این پست سعی درام که این پروژه متن‌باز رو معرفی کنم. خب اول باید بگم که شما برای هر پروژه جدید نیاز دارید که چندتا چیز رو مشخص کنید

  1. اینکه بدونید سورس پروژه کجاست.
  2. اینکه فولدرهایی که header ها توش قرار گرفته کجاست
  3. اینکه بدونید برنامه‌تون به چه کتابخانه‌هایی نیاز داره
  4. اینکه بدونید برنامه‌تون برای کامپیال شدن به کمک GCC به چه flagهایی نیاز داره.

بعد از اینکه این موارد رو دونستید و اونها رو پیدا کردید باید برید و بخشها مرتبط با این موارد رو توی makefile تغییر بدید به عنوان Customizable Section مشخص شده.


		

خب هر یک از این بخش‌های قابل تغییر برای خودش معنایی داره

  1. بخش مقدار flag هایی هست که برای کامپیال کردن فایلها با پسوند c به کار میره. لازه به ذکره که بدونید flagهای C با C++ می‌تونن تفاوت اساسی داشته باشند
  2. بخش نشون‌دهنده flag هایی هست که در فاز link قرار به linker داده بشه و با استفاده از اون کتابخانه ها شناسونده بشن. یه مثال برای این مقدار هست که میگه کتابخانه مورد نیاز این نرم‌افزار هست
  3. بخش بخشی هست که نشون میده flagهای کامپایل c++ چیا هستن. مثلا که نشون میده میخوایم از استاندارد C++ 2011 استفاده کنیم. فولدر headerها رو هم توی این بخش اضافه می‌کنیم
  4. اگه به هر دلیل بخوایم flagهای دیگه ای به linker بدیم از استفاده می‌کنیم.
  5. سورس نرم‌افزار رو با جاهایی که سورس قرار گرفته رو نشون میده.
  6. و در نهایت نام نرم‌افزار رو نشون میده.

امیدوارم با این توضیحات کوتاه دستتون اومده باشه که چه کاری رو به چه صورت باید انجام بدید و در صورت هرگونه سوالی کامنت بگذارید و یادتون نره که من هنوز makefile رو بخوبی بلد نیستم! 😉

لذت برنامه نویسی: IPython Notebook یا Jupyter Notebook

اینم یه تجربه پراکنده دیگه!

من این چند روز بخاطر یه کاری نیاز داشتم یه مساله تئوری گراف رو حل کنم. من معمولا سعی میکنم که توی کارها یه چیز جدید رو یاد بگیرم. به همین خاطر با استفاده از ipython notebook یا jupyter notebook مساله رو حل کردم. اتفاقا جادی هم یه ویدئوی آموزشی خوب در موردش ساخته.

چرا Jupyter Notebook

خب اول از همه میخوام یه چیزایی رو توضیح بدم که به نظر من چرا شاید کسی بخواد از این سیستم‌ها استفاده کنه. مهم‌ترین استفاده‌ای که من براش داشتم اینه که هر جا که به نظرم میخواستم از matlab استفاده کنم میتونستم از jupyter notebook استفاده کنم. بدین شکل که شما برای خیلی کارهای علمی یه کارهایی رو توی matlab پیاده‌سازی میکنی و تست می‌کنی و وقتی لازم شد واقعا در محیط عملیاتی ازش استفاده کنی اون‌ها رو در محیط عملیاتی دوباره پیاده‌سازی می‌کنی.

خب اولین زبانی که jupyter notebook پشتیبانی میکرده python بوده که مثل زبان matlab ساده بوده و بخاطر پکیج‌های عملی که هر دو زبان دارن پیاده‌سازی کارهای علمی به شدت ساده می‌شه.

دوم اینکه هر دو از مفهوم به نام متغیرهای مشترک بین همه برنامه‌های مختلف پشتیبانی می‌کنن که باعث میشه شما یه کار پر هزینه رو یه بار انجام بدی و نتیجه رو داشته باشی و مراحل بعدی رو براساس اون و بدون نیاز به اجرای از اول اون بخش پر هزینه انجام بدی

سوم اینکه هر دو ابزارهای بسیار خوب و قوی برای کشیدن نمودارهای علمی دارن که باعث میشه گزارش ساختن با اونها راحت باشه.

چهارم اینکه در jupyter notebook شما می‌تونید همزمان که کد می‌نویسید گزارش هم بنویسید. یعنی بلوک‌هایی داریم که توش میشه با استفاده از markdown متن هم بنویسید که در نهایت گزارش کاری که دارید انجام می‌دید هم آماده باشه. لازم نیست تکرار کنم که markdown رو من خیلی دوست دارم(۱ و ۲ و ۳)

یه مثال ساده

حالا کار من این بود که بتونم یه گراف جهت‌دار بدون دور بسازم و بتونم اون رو بکشم. خب اول از هم نحوه ساختن اون. کلا در ریاضی اثبات میشه که اگه بخواید گراف جهت‌دار بدون دور بسازید تنها چیزی که نیاز دارید اینه که توی ماتریس مجاورت اون گراف تنها درایه‌های زیر قطر اصلی ۱ باشن. این تضمین می‌کنه که گراف تولید شده گراف جهت‌دار بدون دور باشه.

اول از همه باید نیازمندی ها رو وارد کرد


		

بعد نوبت به کد ساختن DAG میرسه که کد این کار اینه


		

بعدش هم میشه نمایش دادنش که به سادگی میشه این


		

نتیجه کار هم توی github قرار گرفته و از اینجا قابل مشاهده است.
همین!

OpenWrt و کارهای جانبی آن

اینم یه تجربه پراکنده دیگه!

توی پست قبل من OpenWrt رو معرفی کردم. بعدش هم من پول دادم و یدونه از این روترهای به نسبت ارزون خریدم که usb رو پشتیبانی می‌کرد. حالا خواستم یه پست کوتاه بنویسم که با این دستگاه میشه چه کاری‌های دیگه ای انجام داد انجام داد.

به نظرم لیست کارهای ایناست:
– بخاطر داشتن پکیجهای aria2 و transmission به همراه داشتن usb گزینه مناسبی برای دانلود کردن اتوماتیک هست
– میشه کارهای مدل Internet of Things انجام داد. مثلا میشه یه سری کلید تحت شبکه رو کنترل کرد. این کلیدها با گرفتن یه دستور خاص خاموش یا روشن میشن. پس میشه کلی کار جذاب تو مایه‌های اتوماسیون خانگی و خانه هوشمند و اینا انجام داد.
– میشه بصورت ساده دسترسی به اینترنت رو به ساعاتی محدود کرد. مثلا میشه گفت که فلان دستگاه فقط تو این ساعات به اینترنت درسترسی داره. این به درد دستگاه‌هایی میخوره که امکان زمانبندی کارها توشون وجود نداره
– میشه با کمک minidlna یا emby تبدیلش کرد به یه media server برای اشتراک گذاری فیلم و موسیقی

و کلا چون یه لینوکس با کلی پکیج هست کارهایی بسیار دیگه‌ای هم میشه انجام داد.

همین!

پ. ن. من واسه اینکه usb رو روی یکی از مدلهای tp-link راه بندازم یکبار روتر رو تا دم مرگ بردم و با روشهایی سخت افزاری که تو عکس هست دوباره زندش کردم!

Gogs Logo

چرا لینوکس را دوست دارم: داشتن github در خانه با Gogs

اینم یه تجربه پراکنده دیگه!

این یک پست کوتاهه تا بعدا بیشتر زمان داشته باشیم و بیشتر بنویسیم. همونطور که میدونید گوگل چند سالی هست که زبانی به اسم golang رو درست کرده و آدم‌هایی هم به علت ویژگی‌هایی که داره بهش علاقه پیدا کردن. راه‌حلهای زیادی مبتنی بر این زبان ایجاد شده و مورد استفاده قرار می‌گیره.

یکی از بامزه ترین اونها نرم‌افزاری به نام Gogs هست که سعی کرده با استفاده از ویژگی‌های golang یک راه‌حل برای میزبانی git شبیه به github ایجاد کنه. نصب کردن این راه‌حل به شدت ساده است چون کلا نصب پکیج‌های golang ساده است. اما بزرگترین مشکلی که برای ما وجود داره تحریم از سمت گوگل هست که شما باید به نحوی اون رو برطرف کنید. این سرویس اونقدر قابل اطمینان بوده که آدم‌هایی پیدا شدن و با تغییر اندکی از اون به عنوان یک کپی github استفاده می‌کنند. اسم اون سایت notabug هست و پیشنهاد می‌کنم ببینیدش.

راه اندازی این سرویس حداقل برای من که خیلی کارهای مدیریت سیستمی بلد نیستم خیلی سرراست و خوب بود. امیدوارم این معرفی باعث بشه که شما هم بتونید از اون توی محل کار و حتی خونتون استفاده کنید.

همین!

بروزرسانی: با توجه به اینکه فرود عزیر تجربه contribute کردن به این پروژه رو داشتن، گفتن که نحوه اداره این پروژه خیلی بده و به همین خاطر یک fork از این برنامه به اسم gitea بوجود اومده که انگار بهتر مدیریت میشه. و اینکه کلا توجه داشته باشید که تخم مرغ‌هاتون رو توی یک سبد نگذارید!

چرا لینوکس را دوست دارم: ساخت یک مخزن پکیج on demand برای yum

اینم یه تجربه پراکنده دیگه!

همیش مشکلات و محدودیت‌ها آدم رو به خلاقیت وا میداره اما یه سری محدودیت‌ها هم که به دلیل کار نابلدی یا حماقت افراد شرایط عجیب غریب کاری درست میشه هم اعصاب خورد کنه!(یکی از همکاران بنده که خواننده این وبلاگ هم هست و از قضا قبلا کارهای مدیریتی در شرکت‌های دیگه انجام داده پیشنهاد دادن که الزاما تصمیمات بخاطر کارنابلدی و این چیزا نمیفته بلکه شرایط کاری انقدر عجیب غریبه که فعلا همینه که هست) القصه بگم که به علت نبود sysadmin در شرکت(بخش ما)، قرار شد که من به عنوان توسعه دهنده سرویس، یکی از سرویس‌ها رو deploy کنم. این تصمیم که این کار به یه برنامه نویسی سپرده بشه اشتباهه اما بالاخره شرایط اینجوریه! من بعد از لاگین کردن به سرور سعی کردم که در اولین قدم کل اون سرور رو بروزرسانی کنم اما از قضا دیدم که اینترنت نداره! در خواست دادم که دسترسی اینترنت ایجاد کنن اما اون هم به دلایل عجیب اتفاق نیافتاده. پس مجبور شدم که یه repository محلی از تمام پکیج‌ها درست کنم و اون رو به سرور منتقل کنم. مراح این کار از این قراره. سرور یه centos 6.0 هست

  1. نصب یه centos 6.0 به منظور ایجاد repository
  2. نصب نرم افزاری به نام yumdownloader که در بسته yum-utils قرار داره. این ابزار برای دانلود کردن پکیج‌ها به همراه وابستگی‌هاشون هست.
  3. دانلود کردن پکیج‌هایی که میخوایم به همراه وابستگی‌هاشون به کمک
    yumdownloader --resolve <package>
  4. نصب ابزار createrepo برای ساختن repository
  5. ساختن repository با دستور
    createrepo --database /mnt/local_repo
  6. انتقال این repository به سرور و انجام عملیات بروزرسانی یا نصب

همین!

منبع : این و این

چرا لینوکس را دوست دارم: استخراج کلمات کلیدی از سایت نارنجی

اینم یه تجربه پراکنده دیگه!

بسیار پیش میاد که بازار بعضی چیزها توی مملکت‌ما بصورت ناگهانی داغ بشه و باز سرد بشه. این جو ایجاد شده بعضی وقت‌ها خوب و بعضی وقت‌ها بده و بعضی وقت‌ها دامن من رو هم میگیره. حدودا یک سال پیش تب درست کردن سایتی که خبر جمع کنه و اخبار رو بصورت اتوماتیک دسته بندی کنه داغ بود. بصورت قارچی سرویس‌هایی که اخبار رو جمع آوری میکردن سر از خاک در آوردن و موفق شدن یا شکست خوردن. در این حین من به این نتیجه رسیدم که خوبه که من هم به عنوان یه موضوع جانبی و سرگرمی این کار رو انجام بدم. یکی از مشکلاتی که توی این کار داشتم این بود که دسته بندی درست مطالب تاثیر بسیار زیادی توی احتمال رسیدن افراد به این سایت داره. اما مهمترین چیزی که نبود این بود که لیست کلمات کلیدی فارسی اونم تو حوزه تکنولوژی نبود. پس من تصمیم گرفتم به کمک وب این لیست رو بوجود بیارم

اون موقع تازه نارنجی رو تعطیل کرده بودند اما هنوز سایت سرجاش بود. به علت کیفیت خوب کار دوستان توی نارنجی هم تگ‌هایی که به مطالب داده بودن به عنوان لیست کلمات کلیدی قابل اعتماد بود. پس من به این نتیجه رسیدم که یه سری اسکریپت بنویسم که این کلمات رو استخراج کنم. یکم توی اینترنت گشتم و ابزارهای مربوط به استخراج اطلاعات از صفحات وب(web scraping) رو بررسی کردم. آخرش به این نتیجه رسیدم که پایتون و beautiful soup رو پیدا کردم و به کمک اون اسکریپ رو نوشتم.

خب اول از همه تابع استخراج تمامی url های تمام پست‌های نارنجی هست

 

def getNarenjiURLs(inUrl):
	lst = []
	url = 'http://narenji.ir/'

	# Check if it is a valid URL
	if 'http://' in inUrl:
		url = inUrl
	else:
		url = 'http://' + inUrl

	# logging start time
	rst = time.time()
	# getting URL content
	r  = requests.get(url)
	#logging end time
	rend = time.time()
	
	pst = time.time()
	data = r.text
	 
	# parsing content using Beautiful soupe
	soup = BeautifulSoup(data, 'lxml')

	for link in soup.find_all('div',class_='views-field views-field-title'):
		for a in link.find_all('a'):
			if a['href'].startswith('/'):
				lst.append('http://narenji.ir' + a['href'])
			else :
				lst.append(a['href'])
	pend = time.time()
	#print (' r Time = ' + str(rend - rst) +' p Time ' + str(pend - pst))
	return lst

خب بعدش نوبت میرسه به اینکه توی هر صفحه کلمات کلیدی رو استخراج کنم. با بررسی سورس html سایت متوجه شدم که تمام کلمات کلیدی یه الگوی خاص دارن و اون الگو قابل استخراج بود. کد این کار هم در پایین اومده

def getNarenjiKeywords(inUrl):
	lst = []
	url = ""
	if 'http://' in inUrl:
		url = inUrl
	else:
		url = 'http://' + inUrl

	# logging start time	 
	rst = time.time()
	# getting URL content
	r  = requests.get(url)
	#logging end time
	rend = time.time()

	pst = time.time()

	# parsing content using Beautiful
	data = r.text
	 
	soup = BeautifulSoup(data, 'lxml')
	 
	for link in soup.find('div',class_='meta').findAll('a'):
		lst.append(link.text)
	pend = time.time()

	#print (' r Time = ' + str(rend - rst) +' p Time = ' + str(pend - pst))

	return lst

با توجه به بررسی‌هایی که انجام دادم متوجه شدم اگه این کار رو بخوام بصورت متوالی انجام بدم کلی طول خواهد کشید پس تلاش کردم که کار رو بصورت موازی انجام بدم. پس به ازای هر درخواست یه Thread بالا آوردم و بصورت موازی این کارها رو انجام دادم. یه کد warpper رو این دوتا تابع بصورت زیر نوشتم.

def doUrlWork():
	global urlList
	while True:
		url=qGetUrl.get()
		tmpUrl = getNarenjiURLs(url)
		print ( str(len(tmpUrl)) + ' URLs found')
		urlList.update(set(tmpUrl))
		qGetUrl.task_done()

def doKeywordWork():
	global keys
	while True:
		url=qGetKeywords.get()
		tmpKey = getNarenjiKeywords(url)
		print ( str(len(tmpKey)) + ' keys found')
		keys.update(set(tmpKey))
		qGetKeywords.task_done()

برای اینکه تعداد Thread ها زیاد نشه از یه صف استفاده کردم که الان یادم نیست. همچنین از مجموعه‌های پایتون برای حذف کلمات تکراری استفاده کردم.

پس اگه بخوام کل اسکریپت بصورت یکجا بیارم میشه:

import timeit
import time
from bs4 import BeautifulSoup
import urllib2
import requests
from Queue import Queue
from threading import Thread
import codecs

keys = set([])
urlList = set([])

concurrent = 10

def doUrlWork():
	global urlList
	while True:
		url=qGetUrl.get()
		tmpUrl = getNarenjiURLs(url)
		print ( str(len(tmpUrl)) + ' URLs found')
		urlList.update(set(tmpUrl))
		qGetUrl.task_done()

def doKeywordWork():
	global keys
	while True:
		url=qGetKeywords.get()
		tmpKey = getNarenjiKeywords(url)
		print ( str(len(tmpKey)) + ' keys found')
		keys.update(set(tmpKey))
		qGetKeywords.task_done()

def getNarenjiKeywords(inUrl):
	lst = []
	url = ""
	if 'http://' in inUrl:
		url = inUrl
	else:
		url = 'http://' + inUrl

	# logging start time	 
	rst = time.time()
	# getting URL content
	r  = requests.get(url)
	#logging end time
	rend = time.time()

	pst = time.time()

	# parsing content using Beautiful
	data = r.text
	 
	soup = BeautifulSoup(data, 'lxml')
	 
	for link in soup.find('div',class_='meta').findAll('a'):
		lst.append(link.text)
	pend = time.time()

	#print (' r Time = ' + str(rend - rst) +' p Time = ' + str(pend - pst))

 

به این ترتیب کلمات کلیدی نارنجی بصورت موازی استخراج شد و ذخیره شد!

همین!

چرا لینوکس را دوست دارم: داشتن نسخه latex و html مستندات

اینم یه تجربه پراکنده دیگه!

من به شخصه مدت‌هاست علاقه مندم که مستنداتی که تولید میکنم رو با نرم افزار latex بنویسم اما به هزاران دلیل، که مهم‌ترین عدم توانایی به اشتراک گذاری این فایل‌ها با دیگران(اکثر آدم‌هایی که من باهاشون کار میکنم) نتونستم این ایده رو اجرایی کنم. اما همیشه این علاقه در من وجود داشته و داره. به همین خاطر علمم رو در این زمینه زیاد میکنم. همچنین از وقتی که وبلاگ مینویسم به پست‌های وبلاگم به شکل یک مستند نگاه میکنم و دوست دارم اونها در فرمت لاتک داشته باشم.پس به این نتیجه رسیدم که بگردم و ببینم آیا روشی وجود داره که من مستندات رو به یه فرمت خاص بنویسم و بعدش به html و  فرمت لاتک تبدیل کنم؟

در ابتدای کار شواهدی پیدا کردم که احتمالا این روش وجود داره. اگه با روش مستند سازی doxygen آشنا باشید، مستندات با استفاده از فرمت خاص doxyegen نوشته میشن و این نرم افزار میتونه نتیجه رو به فرمت لاتک و html تبدیل کنه. پس کار امکان پذیره. همچنین یکی دیگه از نیازمندی‌های این راه‌حل برای تبدیل آسون بودنه تا مهاجرت و استفاده از راه حل کم هزینه باشه. همچنین به نظر من نوشتن به فرمت لاتک و html سخته و خیلی «تو دل برو» یا همون user friendly نیست. پس باید این نکته رو هم در پیدا کردن راه حل در نظر بگیرم.

خب حالا برم سراغ راه حلی که برای این مساله پیدا کردم. من از قبل با دو روش ساده نوشتن html که عبارتند از makrdown و reStructuredText بصورت محدودی آشنا بودم و میدونستم که تبدیل این فرمت‌های به html مثل آب خوردن انجام میشه پس نصف مساله حل بود. از اونجایی که من با markdown بیشتر آشنا بودم این زبان ساده شده رو انتخاب کردم. حالا میمونه تبدیل markdown به لاتک که بعد از یه ذره گشتن رسیدم به این دوتا پست(لینک، لینک) و با استفاده از اونها تونستم markdown رو به کمک ابزاری به نام pandoc به لاتک تبدیل کنم و با استفاده از زیپرشین اون رو تبدیل کنم به pdf. حالا مراحل انجام این کار رو اینجا مینویسم

  1. نوشتن مستند به فرمت markdown مثلا
    قسمت اول
    ======================
    
    نیازمندیها
    ======================
    پکیجهای زیر باید نصب شود
    
    ۱٫ پکیج اول
    ۲٫ پکیج اول
    ۳٫ پکیج اول
    
    ۴٫ پکیج اول
    ۵٫ پکیج اول
    
    ۶٫ سلام
    	۱٫ سلام ۲
    	۲٫ سلام ۳
    	۳٫ سلام ۴
    	۴٫ سلام ۵
    	۵٫ سلام ۶
    	۶٫ سلام ۷
    	۷٫ سلام ۸
    	۸٫ سلام ۹
    
    چطور کامپایل کنیم
    ====================
    کامپایل کن دیگه
    
  2. تبدیل این متن به فرمت xelatex با دستور زیر
    pandoc -f markdown --latex-engine=xelatex -R -i a.md -o a.tex
  3. متن نتیجه شده به شکل زیره که اضافاتی داره
    \section{قسمت اول}\label{ux642ux633ux645ux62a-ux627ux648ux644}
    
    \section{نیازمندیها}\label{ux646ux6ccux627ux632ux645ux646ux62fux6ccux647ux627}
    
    پکیجهای زیر باید نصب شود
    
    \begin{enumerate}[<+->]
    \def\labelenumi{\arabic{enumi}.}
    \item
      پکیج اول
    \item
      پکیج اول
    \item
      پکیج اول
    \item
      پکیج اول
    \item
      پکیج اول
    \item
      سلام
    
      \begin{enumerate}[<+->]
      \def\labelenumii{\arabic{enumii}.}
      \itemsep1pt\parskip0pt\parsep0pt
      \item
        سلام ۲
      \item
        سلام ۳
      \item
        سلام ۴
      \item
        سلام ۵
      \item
        سلام ۶
      \item
        سلام ۷
      \item
        سلام ۸
      \item
        سلام ۹
      \end{enumerate}
    \end{enumerate}
    
    \section{چطور کامپایل
    کنیم}\label{ux686ux637ux648ux631-ux6a9ux627ux645ux67eux627ux6ccux644-ux6a9ux646ux6ccux645}
    
    کامپایل کن دیگه
  4. حذف این اضافات با دستورارت زیر
    sed -i.bak 's/\[<+->\]//' a.tex
    sed -i.bak 's/\\def\\labelenumi{\\arabic{enumi}.}//g' a.tex
    sed -i.bak 's/\\itemsep1pt\\parskip0pt\\parsep0pt//g' a.tex
  5. که نتیجه میشه این
    \section{قسمت اول}\label{ux642ux633ux645ux62a-ux627ux648ux644}
    
    \section{نیازمندیها}\label{ux646ux6ccux627ux632ux645ux646ux62fux6ccux647ux627}
    
    پکیجهای زیر باید نصب شود
    
    \begin{enumerate}
    \item
      پکیج اول
    \item
      پکیج اول
    \item
      پکیج اول
    \item
      پکیج اول
    \item
      پکیج اول
    \item
      سلام
    
      \begin{enumerate}
      \item
        سلام ۲
      \item
        سلام ۳
      \item
        سلام ۴
      \item
        سلام ۵
      \item
        سلام ۶
      \item
        سلام ۷
      \item
        سلام ۸
      \item
        سلام ۹
      \end{enumerate}
    \end{enumerate}
    
    \section{چطور کامپایل
    کنیم}\label{ux686ux637ux648ux631-ux6a9ux627ux645ux67eux627ux6ccux644-ux6a9ux646ux6ccux645}
    
    کامپایل کن دیگه
  6. این متن به تنهایی توسط لاتک کامپایل نمیشه و باید یه سری تگ‌های استاندارد لاتک بهش اضافه بشه تا بگه فرمت مستند چیه فونتا چین و از این دست چیزا. بهترین راه برای انجام اینکار داشتن یه فایل دیگه برای اون تگ‌های و include کردن این فایل در اون فایل هست. یه نمونه از اون فایل به این صورته:
    \documentclass[a4paper,12pt]{book}
    \usepackage{aut_test}
    \usepackage[colorlinks,linkcolor=black,citecolor=black]{hyperref}
    \usepackage{graphicx}
    \usepackage{amsthm,amssymb}
    \usepackage{tocbibind}
    \usepackage{listings}
    \usepackage{xepersian}
    \settextfont[Scale=1]{B Zar}
    
    \begin{document}
    \chapter{فصل اول}
    \include{a}
    \end{document}
  7. و با این دستور لاتک رو کامپایل میکنیم
    xelatex  -synctex=-1 doc.tex
  8. و نتیجه توی اینجا قابل مشاهده است.

همین!

کار با kvm بجای virtualbox

اینم یه تجربه پراکنده دیگه!

من سال‌هاست که به لینوکس مهاجرت کردم و روی سیستم اصلیم تنهای یک لینوکس دارم. اما بخاطر موارد متعددی همیشه مجبور بودم یه ماشین مجازی ویندوزی داشته باشم. مهمترین استفاده این ماشین مجازی اجرای office هست. امیدوارم بهم پیشنهاد نکنید که از wine یا play on linux و یا چیزای دیگه برای اجرای office استفاده کنم یا حتی بگید برم سراغ latex به این دلیل که از نظر من نگهداری windows emulator ها سخته و این سیستم ها معمولا یه باگ‌هایی دارن که کار به مشکل بر میخوره، همچنین استفاده از latex امکان collaboration یا همون همکاری روی مستندات رو از بین میبره. از liberoffice هم بخاطر به هم ریختگی متون در نسخه‌های مختلف نمیشه استفاده کرد و اگه تا بحال در دنیای واقعی با آدم‌های مختلف و متفاوت کار کرده باشید میدونید که حاضر نیستن office رو رها کنن.

همچنین واسه موارد خاص نیاز داشتم که، از مجازی سازی استفاده کنم که  امکان اتصال usb به ماشین مجازی رو داشته باشه. به همین خاطر اولین انتخاب من همیشه virtualBox بود. virtualBox مجازی ساز بسیار با کیفیت وخوبیه اما مشکل اساسیش اینه که ما رو تحریم کرده. یعنی نصب کردن و اجراش کار هر کس نیست و معمولا نیاز به جنگولک  بازی‌های بسیاری داره و این از نظر من یعنی سختی نگهداری. من از kvm هم برای حالت‌هایی که نیاز به اتصال سخت افزار خاصی ندارن استفاده می‌کردم اما به علت اینکه virtaulbox همه نیازهای من رو پوشش میداده کم کم دیگه از kvm استفاده نکردم.

تا اینکه چند شب قبل به ذهنم رسید که دوباره یه سری به  kvm بزنم اما این دفعه در کمال ناباوری دیدم که اوضاع خیلی بهتر شده. با تشکر از یه پروژه به اسم spice کلی از مشکلات من حل شده. اول اینکه کارت گرافیکی خاصی نصب میشه و اون کارت امکان تغییر اندازه اتوماتیک رزولوشن صفحه با سایز ویندوزی که اون رو نشون میده، رو فراهم میکنه. دوم اینکه یه چیزی به اسم usb redirector اضافه شده که همون حرکتی که من دوست داشتم یعنی اتصال یه usb رو هم انجام میده نکته قابل توجه هم اینه که virtualbox از usb3 پشتیبانی نمیکنه اما اینجا پشتیبانی انجام میشه. هنوز نتونستم اون ویژگی virtualbox که باهاش یک فولدر رو بین ماشین‌ها به اشتراک میگذاره راه بندازم اما به نظرم همین‌ها کافی که دردسر نصب virtualbox رو بیخیال بشم و برم کاملا سراغ kvm.

همین!