יום שני, יולי 27, 2015

muni grabber

לא היה לי ערוץ RSS להודעות באתר העירייה אז התוצאה לפניכם, יכול להיות שזה יעבוד גם לאחרים אם גם העירייה שלהם משתמשת במערכת ההודעות דומה.
#!/usr/bin/perl  

use LWP 5.64; # Loads all important LWP classes, and makes
use HTTP::Cookies; # Allow work with cookies
use XML::RSS;
use Encode qw(decode encode);

my $browser = LWP::UserAgent->new;
if ( $#ARGV != 0 )  {
 print  "incorrect number of  params, you should provide only basepath example : $0 http://url.muni.tld\n";
 die "";
}

$browser->cookie_jar( HTTP::Cookies->new(
    'file' => '/tmp/headers',
        # where to read/write cookies
    'autosave' => 1,
        # save it to disk when done
  ));



$browser->agent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
my $basepath = "$ARGV[0]";
my $url = "$basepath/openning.asp?Lang=1";
my $response = $browser->get( $url );


#for each cookie we got, add it to the current jar
$browser->cookie_jar->extract_cookies( $response );

$response = $browser->get( "$basepath/apps/hebrew/resulttest.asp?AppId=4&TableName=MESSAGES&Categories=65&From=" );

my $rss = XML::RSS->new( version => '0.9' );
          $rss->channel(
          title        => "MUNI for $basepath",
          link         => "$basepath",
          description  => "MUNI RSS");

#the intersting stuff is inside Parse_Html_Template(...)
#I was too lazy to use better modules so I just went to the source , please don't shoot me ;)
#
#
for my $item ($response->content  =~ /Parse_Html_Template\((.*?)\)/g) {
    #first line always have garbage data (just skip it)
    next unless ($item =~ /.*,.*/) ;
    #Format  #### , "title","date"
    # ### may be a version number 
    #
    #
    $item =~ s/[^,]*,[^,]*,[^,]*,//;#remove useless headers
    #the next come in the format : 
    #"<a href='relative_path'>text</a>","<a href='relative path'>date</a>"
    while  ( $item  =~ q/"([^"]*)","([^"]*)"/)
    {
       my $firstpart = $1 ;
       my $secondpart = $2 ;
       $firstpart=~ /<a.*href=["']([\s\S]+?)['"].*>/;
       $link = $1;
       $firstpart=~ /<a.*href.*>([\s\S]+?)<\/a>/;
       $text = $1;
       $text =   decode("iso-8859-8", $text);
       $rss->add_item( title => $text, link => $basepath . $link);
       $item =~ s/"([^"]*)","([^"]*)"//;
    }
}

$rss->save("$0.rss");

__END__

=head1 NAME

muni RSS - a script to get an RSS from old municipal websites which are lacking an RSS/Atom features. 

=head1 SYNOPSIS

Create an RSS 0.9 file based on the messages page.

=head1 DESCRIPTION

This script provide a basic example on how one could get the RSS from the rusty pages without the RSS interface, 

=head1 BUGS

=head1 AUTHOR

Original code:Boris Shtrasman 

=head1 COPYRIGHT

Copyright (c) 2015 Boris Shtrasman 

=head1 LICENSE

this script is free software. You can redistribute it and/or modify it under the same terms as Perl itself.

=head1 CREDITS

Rael Dornfest <rael@oreilly.com>
Jonathan Eisenzopf <eisen@pobox.com>
Wojciech Zwiefka <wojtekz@cnt.pl>
Chris Nandor <pudge@pobox.com>

=head1 SEE ALSO

perl(1), XML::Parser(3), LWP(3), XML::RSS(3),HTTP::Cookies(3)

=cut


יום שני, יולי 13, 2015

המלך מת, יחי המלך !

השבוע ראיתי כי שירות ה XMPP של פייסבוק שוב עושה צרות,  והספרייה הסגולה נכשלת בחיבור.
בערוץ pidgin הפנו אותי לי לפלאגין שמאפשר עבודה חלקית.








לצערי גיליתי כי מספר פיטצרים שעבדו מצויין בפלאגין ה XMPP אינם עובדים כמו : 
  • יכולת לשלוח הודעות לאנשים ששלחת / הם שלחו בקשת חברות אבל זו לא אושרה.
  • קבלת פרטים עבור משתמשים ברשימת אנשי הקשר
בגלל שלא מדובר במשהוא מתוך הספריה הדבר אומר כי הלקוחות שמשתמשים ב libpurple אינם יכולים לגשת לשרתי הדיון של פייסבוק (xabber/kopete וכו).

יום ראשון, יולי 12, 2015

אם זה טפשי אבל עובד , זה לא טפשי

לא מצאתי פתרון נוח למשוך יומנים מ meetup , כפתרון זמני מצאתי כי אם אני משתמש במפתח API אני יכול פשוט לשלוף את ה ical ים של הקבוצות המעניינות.

דוגמית:
#!/bin/bash

#meetupapikey    is the meetup api key for a specific user
#ownclouusername is a username defined on the owncloud server

meetupgroups=("name1"  "name2" "name3" "name4"  ) # space separated names
for i in "${meetupgroups[@]}"
do
  wget http://api.meetup.com/$i/upcoming.ical?key=${meetupapikey} -O $i.ical
done

cadaver -t  https://owncloud.local/owncloud/remote.php/caldav/calendars/${ownclouusername}/personal << END
  mput *.ical
  exit
END






צריך לזכור להוסיף את הסרטיפיקט ולמלא את .netrc  בשביל ש cadaver יוכל להתחבר אוטומטית:

user@laptop:~$ cat ~/.netrc 
machine owncloud.local
login   ownclouusername
password ownclodpassword

יום רביעי, אפריל 15, 2015

וחייה היונה ביחד עם Lync

בשעה טובה ומצלחת קיבלתי גישה לשירות ה Lync  עבור המשתמש שלי , השירות שלי מסופק ע"י  Office365 ללא אחסון מקומי.

שם המשתמש שלי לחיבור עבור office365 הוא user@myerfm.blogspot.com והסיסמה היא secret.

 אצתי רצתי ליונה (pidgin) התקנתי את SIPE (יאפ על וינדוס) אז  :


לאחר מכן בטאב של מאפיינים מתקדמים יש למלא :

החלק החשוב זה ה UA אצלי עבד עם :
UCCAPI/15.0.4420.1017 OC/15.0.4420.1017 (Microsoft Lync)


מה לא עובד :

ביצוע שיחות קוליות (צד שני לא מקבל התראה על שיחה נכנסת).
העברת קבצים. 

מה כן עבד :
IM
OTR עושה קולות של עובד.
חיפוש והוספת משתמשים מאנשי הקשר ב office365
 

יום ראשון, אפריל 05, 2015

חוויות בתהליך מעבר ל CMAKE + c++11 שלום עולם

התמזל מזלי ומתנה נפלה בחלקי העברת קוד שמשתמש במגוון ספריות לשימוש ב C++11 יחסית ביחד עם CMake.

התהליך התעכב רבות והתחיל רק השבוע פה לכן אני חושב לרכז מספר הגיגים על התהליך.

אני מקווה לטוב ולכן נכון לעכשיו אני בודק רק על gcc אבל אני מקווה שהכל ילך חלק וזה גם יעבוד על VS 2013 איתו אני עובד יותר.

CMakeLists עבור שלום עולם יראה כך :

cmake_minimum_required(VERSION 2.6)
project(hello_world)
FIND_PACKAGE (Threads)


if (CMAKE_COMPILER_IS_GNUCXX)
  SET(CMAKE_CXX_FLAGS "-std=gnu++11") # for C++11 in gcc
endif()

add_executable(hello_world main.cpp)
target_link_libraries (hello_world ${CMAKE_THREAD_LIBS_INIT})


install(TARGETS hello_world RUNTIME DESTINATION bin)

הוספת המשתנה CMAKE_CXX_FLAGS פותרת את:


In file included from /usr/include/c++/4.9/thread:35:0,
                 from /opt/video/wasteoftime/cpp/threading/proj/hello_world/main.cpp:2:
/usr/include/c++/4.9/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
 #error This file requires compiler and library support for the \
  ^ 


השימוש ב ${CMAKE_THREAD_LIBS_INIT} דרוש בשביל שניתן יהיה להשתמש בנימים , ועל הדרך פותר החריגה (שאין לי שמץ למה היא קוראת)
terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1

כאשר משתמשים ב std::call_once (אני לא יודע אם זה באג או שאני פשוט מפספס משהוא בסיסי) ולא מתלנקקים מול pthread דוגמאת קוד לריסוק:

#include <iostream>
#include <mutex>

class resource
{
  std::once_flag resource_flag;
  void init_once(){}
public:
  resource(){};
  ~resource(){};
  void  doSomething()
  {
    std::call_once(resource_flag,&resource::init_once,this);
    return;
  }
};

int main()
{
  resource r;
  r.doSomething();
  return 0;
}

ככלל קוד שלום עולם נראה כך :

#include <iostream>
#include <thread>

static void f()
{
    std::cout << "Hello, world!" << std::endl;
}

int main(int argc, char **argv) {
  
    std::thread t (f);
    t.join();
    return 0;
} 
הפתעה כואבת היתה (כן כן אני יודע באג של מתחילים) כאשר העברתי ייחוס (reference) לאובייקט ארעי במקום לאובייקט עצמו (קוד שיעורי בית עם באג) :

#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
int accum = 0;

void square (int x , std::mutex & mutex) 
{
  std::lock_guard <std::mutex> guard( mutex);
  accum += x * x;
}

int main()
{
  std::vector < std::thread> threads;
  std::mutex mutex;
  for (int i = 1; i < 21 ; i ++ )
  {
     threads.push_back(std::thread (  square, i,mutex)) ; 
  }
  for (std::vector < std::thread>::iterator it = threads.begin();it != threads.end();++it)
  {
    it->join();
  }
  std::cout << accum << std::endl;
  return 0;
}

הנקודה הבעייתית במקרה של העברת ייחוס לאובייקט אירעי ולא לאובייקט עצמו:

     threads.push_back(std::thread (  square, i,mutex)) ; 
הקוד הנכון הוא :
     threads.push_back(std::thread (  square, i,std::ref (mutex) )) ; 

הופתעתי לטובה כי ניתן להשתמש די בקלות בהעברת חריגות כמעת בצורה זהה לבוסט קוד (קוד דוגמא) בבוסט :

#include <boost/exception/all.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>

void avodashora()
{
  if (  rand () % 100 == 0)
  {
    throw boost::enable_current_exception(std::runtime_error("piturim"));
  }
}

class oved_cablan
{
public:
  void operator()(boost::exception_ptr & tzarot)  
  {
    try 
    {
      while (true)
      {
        avodashora();
      } 
    }
    catch (...)
    {
      tzarot = boost::current_exception();
    }
  }
};

class dor_aleph
{
public:
    dor_aleph(): 
    ben_dod_shel
    (
      boost::bind 
      (
        &oved_cablan::operator(),
        boost::ref(oved_pashut),
        boost::ref( tzarot ) 
      ) 
    )
    {
      //a dor_aleph , needs ben_dod_shel to the work for him
      //any problem that ben_dod_shel will get be refernced to oved_pashut
    }

    void work()
    {
      ben_dod_shel.join();//our dor aleph need to wait till ha ben dod will finish the work he assigned to

      if (tzarot)
      {
        boost::rethrow_exception( tzarot );
      }
    }
private:
    oved_cablan          oved_pashut;
    boost::thread        ben_dod_shel;
    boost::exception_ptr tzarot;
};

int main()
{
  try
  {
   dor_aleph a;
   a.work();
  }
  catch (std::exception & e)
  {
    std::cout << e.what() << std::endl;
  }
  return 0;
}
הקוד המומר לc++11

#include <boost/exception/all.hpp>
#include <iostream>
#include <thread>

void avodashora()
{
  if (  rand () % 100 == 0)
  {
    throw std::runtime_error("piturim");
  }
}

class oved_cablan
{
public:
  void operator()(std::exception_ptr & tzarot)  
  {
    try 
    {
      while (true)
      {
        avodashora();
      } 
    }
    catch (...)
    {
      tzarot = std::current_exception();
    }
  }
};

class dor_aleph
{
public:
    dor_aleph(): 
    ben_dod_shel(oved_pashut,std::ref(tzarot))
    {
      //a dor_aleph , needs ben_dod_shel to the work for him
      //any problem that ben_dod_shel will get be refernced to oved_pashut
    }

    void work()
    {
      ben_dod_shel.join();//our dor aleph need to wait till ha ben dod will finish the work he assigned to

      if (tzarot)
      {
        std::rethrow_exception( tzarot );
      }
    }
private:
    oved_cablan        oved_pashut;
    std::thread        ben_dod_shel;
    std::exception_ptr tzarot;
};

int main()
{
  try
  {
   dor_aleph a;
   a.work();
  }
  catch (std::exception & e)
  {
    std::cout << e.what() << std::endl;
  }
  return 0;
}