tag:blogger.com,1999:blog-33678306694837199812024-03-14T10:14:48.874+01:00A Roller Coaster RideAshhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.comBlogger18125tag:blogger.com,1999:blog-3367830669483719981.post-153649790374100572010-12-31T18:29:00.005+01:002011-01-01T17:42:22.547+01:00Proxying Server from Apache on SynologyHow to redirect a part of your web site to another server on your LAN:<br />
<br />
... On your NAS: at the bottom of <i>/usr/syno/apache/conf/httpd.conf-user</i><br />
<br />
<pre class="brush: xml">ProxyRequests Off
<proxy *>
Order deny,allow
Allow from all
</proxy>
ProxyPass /redmine http://192.168.0.78/redmine
ProxyPassReverse /redmine http://192.168.0.78/redmine
<location redmine>
AuthName "Protected Access"
AuthType Basic
AuthUserFile /var/services/web/hg/.htpasswd
require valid-user
</location>
</pre><br />
<br />
It tells Apache to redirect all /redmine/* access to another server (this subdirectory is protected by password in this case).<br />
<br />
And... That's all :)Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-56039369109432738822010-12-31T16:21:00.006+01:002011-01-01T18:01:47.764+01:00Virtual machine as Windows serviceA follow up from<br />
<a href="http://ash-ride.blogspot.com/2010/11/synology-as-web-gateway.html">Synology as Web Gateway (part one)</a><br />
Once you have a virtual server up and running in Virtualbox, the question of starting it automatically in the background may be solved by the use of <b>ServiceMan</b>.<br />
<br />
<b>ServiceMan</b> is a small win32 app i wrote as Virtualbox (3.xx) is not natively service-able. It features execution of a set of cmd lines, and on-the-fly environment variables setting. Both are needed to start a virtualbox machine (plus is able to launch many apps in one go, and support internal variables).<br />
<br />
You need to type a cmd line to register <b>ServiceMan</b> as a service (it will be executed at host start).<br />
<blockquote><span style="font-family: "Courier New",Courier,monospace;">ServiceMan -i [ServiceName]</span></blockquote><br />
<b>ServiceMan</b> will get all information from a old-fashioned <i>ServiceMan.ini</i> located in the executable directory. Here is mine in this case:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace; font-size: small;"><br />
<br />
[General]<br />
;this shows in services control panel<br />
Description=ServiceMan (a virtual machine using virtualbox)<br />
<br />
;<br />
;From now, each section is considered to be triggered sequentially <br />
;at host startup and shutdown<br />
;<br />
;We're launching a virtual server in this one<br />
[VirtualUbuntu]<br />
<br />
;<br />
;Aliases : allow to define internal variables you'll be reusing later in config file<br />
;here i'm using a portable edition of virtualbox, and need to set some paths<br />
;<br />
Aliases=VboxUserHome=D:\Machines\Portable-VirtualBox\data\.VirtualBox;VboxDir=D:\Machines\Portable-VirtualBox\app64<br />
<br />
;A more conventional virtual box installation should use this<br />
;Aliases=VboxUserHome=C:\Documents and Settings\[User Name]\.VirtualBox;VboxDir=C:\Program Files\Oracle\VirtualBox<br />
<br />
;<br />
;Environment variables to add to your configuration when executing cmd lines<br />
;<br />
EnvVars=VBOX_USER_HOME=%VboxUserHome%;VBOX_INSTALL_PATH=%VBoxDir%<br />
<br />
;<br />
;Working directory<br />
;<br />
WorkingDir=%VboxDir%<br />
<br />
;<br />
;we can redefine envvars for that particular service event<br />
;with StartupEnvVars=VBOX_USER_HOME=%VboxUserHome%;VBOX_INSTALL_PATH=%VBoxDir%<br />
;following are the command executed sequentially. It waits 1000s by default<br />
;<br />
;doing this should force vboxsvc to read new env vars<br />
StartupCmd1="%VboxDir%\vboxsvc.exe" /reregserver<br />
;it's possible to define a pause between commands (default is 1000 ms) <br />
;StartupPause1=1000<br />
StartupCmd2="%VboxDir%\vboxmanage.exe" list systemproperties<br />
StartupCmd3="%VboxDir%\vboxmanage.exe" list vms<br />
StartupCmd4="%VboxDir%\vboxheadless.exe" -startvm VirtualLinux<br />
<br />
;<br />
;and shutdown event: again, if we need to redefine things...<br />
;ShutdownEnvVars=VBOX_USER_HOME=%VboxUserHome%;VBOX_INSTALL_PATH=%VBoxDir%<br />
;ShutdownWorkingDir=%VboxDir%<br />
;<br />
ShutdownCmd1="%VboxDir%\vboxmanage.exe" controlvm VirtualLinux savestate<br />
<br />
;<br />
;you may have more than one app to launch as a service: open another section <br />
;[AnotherSetOfCommand]<br />
;etc, etc<br />
;<br />
</span><br />
<br />
<br />
If you need to start and stop for testing, use the service control panel or the cmd line -s / -k option.<br />
<br />
Note that it generates a session exec log in ServiceMan directory (which, therefore, should be writable).<br />
<br />
Download <a href="http://alimbourg.free.fr/ServiceMan.zip">ServiceMan</a>Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-17406369745227828852010-11-24T21:29:00.009+01:002011-01-02T18:21:30.207+01:00Synology as Web gateway (part1)<div style="font-family: inherit;"><a href="http://www.redmine.org/">RedMine</a> is a great tool for developpers: unfortunately it does not perform well on my synology DS-107+ (for various reasons i don't have time to inspect, low memory is probably a first answer)...</div><div style="font-family: inherit;"><br />
</div><div style="font-family: inherit;">Anyway, as i'm having a-lot-of (probably too-much) machines available @ home: i choose to dedicate some horsepower to run a minimalistic virtual linux machine with Apache and RedMine (note that <a href="http://bitnami.org/">Bitnami</a> is offering such packages ready for download).</div><div style="font-family: inherit;"><br />
</div><div style="font-family: inherit;">So my idea was to use the Synology as a gateway between the internet and my home LAN, mainly to centralize security settings, and access point uniqueness.</div><div style="font-family: inherit;"></div><div style="font-family: inherit;"><br />
Many topics are covered in this recipe: </div><div style="font-family: inherit;"><br />
</div><div style="font-family: inherit;">1) Installing a virtual ubuntu server running redmine<br />
<a href="http://ash-ride.blogspot.com/2010/12/virtual-machine-as-windows-service-web.html">2) Running a virtual machine as a service under Windows 7</a></div><a href="http://ash-ride.blogspot.com/2010/12/proxying-server-from-apache-on-synology.html">3) Binding the Synology web frontend and a virtual server</a> <br />
<br />
<div style="font-family: inherit;"></div><div style="font-family: inherit;"></div><div style="font-family: inherit;"><span style="font-size: large;">Creating the virtual machine : ubuntu+redmine</span></div><div style="font-family: inherit;"></div><b>Get VirtualBox</b>, <a href="http://www.virtualbox.org/">http://www.virtualbox.org/</a> . Eventually look for a portable edition.<ul></ul><b>Create a new virtual machine</b>: Ubuntu type, i dedicated 20gb of expandable disk space and 512Mo memory (but 5Go and 256Mo should be fine). Use <b>Bridged Network Access</b> for network connections (it should allow the virtual machine to have its own static IP address on your LAN).<ul></ul><blockquote>Note: to move a virtual server from one machine to another: ensure that you're using the same netword card between virtualbox installations: type of network card and MAC address <b>must</b> be the same. (note that if network is not working properly on virtualized linux, ensure that <i>/etc/udev/rules.d/70-persistent-net.rules</i> doesn't contain deprecated MAC entries).</blockquote><b>Grab Ubuntu server ISO</b>, attach it to your virtua machine and perform the (blazingly fast) install: select <i>Apache </i>and <i>MySQL</i> components <ul></ul><div style="font-family: inherit;"><ul><li>Once connected to the console, you might notice a sluggish refresh:</li>
</ul></div><blockquote>howto blackList vga mode :<br />
<span style="font-family: "Courier New",Courier,monospace;">sudo nano /etc/modprobe.d/blacklist-framebuffer.conf</span><br />
add the following line: <br />
<span style="font-family: "Courier New",Courier,monospace;">blacklist vga16fb</span></blockquote><blockquote><div style="font-family: inherit;">Note: you can enable and use remote access to a virtualbox machine...</div></blockquote><b>Enforcing static IP use for the virtual Ubuntu Server</b> (192.168.0.78 in my case) <ul></ul><br />
<div style="font-family: inherit;"><ul></ul></div><blockquote><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">sudo vi /etc/network/interfaces </span></div>change<br />
<blockquote style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">auto eth0</span><br />
<div><span style="font-size: small;">iface eth0 inet dhcp</span></div></blockquote>into<br />
<blockquote><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">auto eth0</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">iface eth0 inet static</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">address 192.168.0.78</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">netmask 255.255.255.0</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">network 192.168.0.0</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">broadcast 192.168.0.255</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">gateway 192.168.0.254</span></span></blockquote>store your dns info via <br />
<blockquote><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">sudo vi /etc/resolv.conf</span></span></blockquote></blockquote><blockquote><blockquote>you should read/add something like this</blockquote><blockquote><blockquote><pre>nameserver 208.67.220.220
nameserver 208.67.222.222</pre></blockquote></blockquote></blockquote><blockquote> and finally</blockquote><blockquote style="font-family: "Courier New",Courier,monospace;"><blockquote><div><span style="font-size: small;">sudo /etc/init.d/networking restart </span></div></blockquote></blockquote><b>Install VirtualBox extensions</b> on ubuntu servers<ul></ul><blockquote><div style="font-family: inherit;"><span style="font-size: small;"><code>apt-get install build-essential linux-headers-`uname -r`</code></span></div><div style="font-family: inherit;"><span style="font-size: small;"><code>mount /dev/cdrom /media/cdrom</code></span></div><div style="font-family: inherit;"><span style="font-size: small;"><code>cd /media/cdrom</code></span></div><div style="font-family: inherit;"><span style="font-size: small;"><code>./VBoxLinuxAdditions-x86.run</code></span></div></blockquote><div style="font-family: inherit;"></div><div style="font-family: inherit;"></div><b>Perform Ubuntu system update</b>:<ul></ul><blockquote style="font-family: "Courier New",Courier,monospace;"><div><span style="font-size: small;">sudo apt-get update</span></div><div><span style="font-size: small;">sudo apt-get install ruby </span></div><div><span style="font-size: small;">sudo apt-get install rubygems </span></div></blockquote><b>Install Ruby requirements</b> for RedMine <ul></ul><blockquote><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">sudo gem install </span><br />
<span style="font-size: small;">gem install rails -v 2.3.5 -no-doc -no-ri</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">gem install rack -v 1.0.1 -no-doc -no-ri</span></div></blockquote><b>Plug Ruby with MySQL</b>, using an adapter:<ul></ul><blockquote style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">cd /tmp</span><br />
<div><span style="font-size: small;">check latest version http://github.com/tmtm/ruby-mysql/downloads</span></div><span style="font-size: small;">wget http://github.com/downloads/tmtm/ruby-mysql/ruby-mysql-2.9.3-beta.tar.gz</span><br />
<span style="font-size: small;">tar -xzvf ruby-mysql-2.9.3-beta.tar.gz</span><br />
<span style="font-size: small;">cd ruby-mysql-2.9.3-beta/</span><br />
<span style="font-size: small;">ruby setup.rb</span></blockquote><b>Eventually install PHPMyAdmin</b> <ul></ul><blockquote><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">sudo wget http://sourceforge.net/projects/phpmyadmin/files%2FphpMyAdmin%2F3.3.7%2FphpMyAdmin-3.3.7-all-languages.tar.gz </span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">sudo tar -xzvf </span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">sudo mv /apps/phpMyAdmin</span></div></blockquote><div style="font-family: inherit;"></div><blockquote><span style="font-family: inherit;">On Ubuntu Server: symbolic links in <i>/etc/apache2/sites-enabled</i> point to 'available' web sites. Use the <i>a2ensite</i> (Apache2 Enable Site) command to create such symbolic links, like this: <i> </i></span><i><span class="command" style="font-family: inherit;">sudo a2ensite mynewsite</span></i><span style="font-family: inherit;"> where your site configuration file is </span><code class="filename" style="font-family: inherit;"> <i>/etc/apache2/sites-available/mynewsite </i></code><span style="font-family: inherit;">. Similarly, the <i>a2dissite</i> utility is used to disable sites.</span></blockquote><div style="font-family: inherit;"><b>Enabling your PhpMyAdmin</b> directory as a site<ul></ul><blockquote><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">cd /etc/apache2/sites-available </span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">ln /phpmyadmin /apps/phpmyadmin-3.3.7</span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">sudo a2ensite phpmyadmin</span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> /etc/init.d/apache2 reload</span></span></blockquote></div><blockquote><div style="font-family: inherit;">browse to address/phpmyadmin </div><div style="font-family: inherit;">login/root from installation credentials</div><div style="font-family: inherit;">sometimes php fails when triggered (security problems), edit</div><div style="font-family: "Courier New",Courier,monospace;">sudo nano /etc/php5/apache2/php.ini</div><div style="font-family: inherit;">and edit <i>open_basedir =</i> to add your own '/apps/' (which allow php execution from that directory).</div></blockquote><b>Install Mercurial</b><ul></ul><div style="font-family: inherit;"></div><blockquote style="font-family: "Courier New",Courier,monospace;"><div><span style="font-size: small;">sudo apt-get install mercurial </span></div></blockquote><b>Download and configure Redmine</b> (<a href="http://www.redmine.org/wiki/redmine/RedmineInstall">http://www.redmine.org/wiki/redmine/RedmineInstall</a>) <ul></ul><div style="font-family: inherit;"></div><blockquote style="font-family: inherit;"></blockquote><blockquote><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">chown -R www-data:www-data /apps/</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">cd /volume1/apps</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">wget http://rubyforge.org/frs/download.php/72201/redmine-1.0.1.tar.gz</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">tar -xzvf redmine-1.0.1.tar.gz</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">mv redmine-1.0.1 redmine</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">cd redmine/config </span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">cp database.yml.sample database.yml</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">nano /config/database.yml</span></span><br />
<blockquote><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">production</span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> adapter: mysql</span></span></blockquote><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> username: redmine</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> password: xxxxxxxx</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">sudo apt-get install libopenssl-ruby1.8</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">sudo apt-get install rake </span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">cd redmine</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">RAILS_ENV=production rake config/initializers/session_store.rb</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">RAILS_ENV=production rake db:migrate</span></span></blockquote><blockquote style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">RAILS_ENV=production rake redmine:load_default_data<br />
ruby script/server -p production<br />
<br />
in redmine login/password: admin admin</span></blockquote><br />
<b>Install passenger</b> (module enabling execution of ruby servicing in Apache)<ul></ul><blockquote><pre class="commands" style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">sudo apt-get install libapache2-mod-passenger</span></pre><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"></span></div></blockquote><blockquote style="font-family: inherit;"><div><span style="font-size: small;">load module in sites apache config scripts if not included by default </span></div></blockquote><div style="font-family: inherit;"></div><blockquote><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">LoadModule passenger_module modules/mod_passenger.so </span></div></blockquote><br />
<div style="font-family: inherit;"></div><pre class="commands" style="font-family: inherit;"><b>Install RedMine site under Apache</b> (http://www.he1ix.org/?p=572)</pre><ul></ul><blockquote style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">cd /etc/apache2/sites-available <br />
Alias /redmine /apps/redmine-1.0.1/public<br />
sudo a2ensite redmine<br />
sudo /etc/init.d/apache2 reload<br />
sudo chown -R www-data.www-data files log tmp public/plugin_assets<br />
sudo a2enmod rewrite<br />
cd /apps/redmine-1.0.1/public<br />
copy dispatch.cgi.example dispatch.cgi </span></blockquote><blockquote><div style="font-family: inherit;">If you have problem with <i>/tmp/mysql.sock</i> (Redmine having some problems to access mysql: can't find /tmp/mysql.sock):</div></blockquote><blockquote><div style="font-family: inherit;">you cant use <i>sudo ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock</i> (file is not persistent), but you may specify the ubuntu mysql socket path in redmine config: edit /redmine/config/database.yml </div></blockquote><blockquote><div class="comment" style="font-family: inherit;"><pre class="wiki"><span style="font-size: small;">production:
adapter: mysql
socket: /var/run/mysqld/mysqld.sock</span></pre><pre class="wiki"><span style="font-size: small;">
</span></pre></div></blockquote><div style="font-family: inherit;"></div><b>Enabling NFS services on your synology</b>: to allow your LAN machine to access a repository on the synology<ul></ul><blockquote style="font-family: "Courier New",Courier,monospace;"><div><span style="font-size: x-small;"></span></div><blockquote>synoservice --list <br />
synoservice --enable nfs<br />
nano /etc/exports<br />
<br />
<span style="font-family: Verdana,sans-serif;">In 'exports' file, add the following line </span><br />
<span style="font-size: x-small;">/directory/ ip.of.NFS.client(ro,root_squash,no_subtree_check)</span><br />
(* as 'ip.of.NFS.client', means 'for all computers on LAN')<br />
<br />
<span style="font-family: Verdana,sans-serif;">Save the 'exports' file </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Check if the file </span>/var/lib/nfs/rmtab <span style="font-family: Verdana,sans-serif;">does exist, if not, run the following command </span><br />
touch /var/lib/nfs/rmtab<br />
<br />
<span style="font-family: Verdana,sans-serif;">Now perform </span><br />
cd / /usr/sbin/exportfs -a<br />
<br />
<span style="font-family: Verdana,sans-serif;">Testing: look at <span style="font-family: "Courier New",Courier,monospace;">/var/log/messages</span> to check whether the settings are ok with your Synology product </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">On the Ubuntu Server side (read </span><a href="http://www.techotopia.com/index.php/Sharing_Ubuntu_Linux_Folders_with_Remote_Linux_and_UNIX_Systems" style="font-family: Verdana,sans-serif;">this</a><span style="font-family: Verdana,sans-serif;">):</span><br />
<br />
sudo apt-get install nfs-kernel-server <br />
sudo mkdir /apps/mnt<br />
sudo mount 192.168.0.77:/volume1/repos<br />
<br />
sudo vi /etc/fstab</blockquote></blockquote><blockquote><blockquote>to add </blockquote></blockquote><blockquote style="font-family: "Courier New",Courier,monospace;"><blockquote>192.168.0.77:/volume1/repos /nfsmount nfs</blockquote></blockquote><b>That's it for the virtual ubuntu server install !</b> <ul></ul><br />
<div style="font-family: "Courier New",Courier,monospace;"></div>Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-58604761673607076722010-09-26T14:18:00.014+02:002011-01-01T16:21:11.280+01:00RedMine (Synology)<a href="http://www.redmine.org/">RedMine</a> is a great project/content management targeted at developers. I'm personnally using it as a complementary tool alongside Mercurial source code repository (cf previous posts): <br />
<br />
And after a terrible fight, i managed to get Redmine running on my Synology through Apache. <br />
<br />
First, Redmine is coded with Ruby, and that's partially a problem concerning the webserver to run this Web App. CGI interface is deprecated, and Mongrel, Thin, Unicorn, FastCGI gems (which are the usual suspects :)) are not built for our plateform. After spending some days trying, i resign myself using Webrick (which is not intended for production use, but for development, anyways it's working out of the box).<br />
<br />
Using Webrick, our ruby webapp will run standalone, accessible via http port 3000. If you want to use Apache to access it (because you cant access port 3000 from the outside, because you need secured transations) you'll need to set 'reverse proxying' to map one of your Apache web directory (<a href="https://diskstation/redmine/">https://diskstation/redmine/</a> ) to Webrick server. <br />
<br />
<b>The most important about this installation is these references</b>: <br />
<a href="http://wiki.joachimschuster.de/index.php/Install_Ruby_on_Rails_and_Redmine_on_DS210%2B">http://wiki.joachimschuster.de/index.php/Install_Ruby_on_Rails_and_Redmine_on_DS210%2B</a><br />
(choose the 'root install' way) <br />
<a href="http://www.vinc3nt.fr/2010/03/installer-redmine-sur-un-synology-ds209ii/">http://www.vinc3nt.fr/2010/03/installer-redmine-sur-un-synology-ds209ii/</a><br />
(in french, use a dedicated redmine user which complicates things a little)<br />
<a href="http://www.redmine.org/wiki/redmine/RedmineInstall">http://www.redmine.org/wiki/redmine/RedmineInstall</a><br />
(Redmine official install howto) <br />
<a href="http://www.redmine.org/wiki/1/HowTo_Install_Redmine_in_a_sub-URI">http://www.redmine.org/wiki/1/HowTo_Install_Redmine_in_a_sub-URI</a><br />
(and finally to connect the running instance with Apache)<br />
<br />
To write it again, the steps are:<br />
<br />
<b> Setup MySQL</b> (no other backend look usable right now)<br />
<br />
Activate MySQL services with Synology Console <br />
Create a 'redmine' database in MySQL (via phpmyadmin) <br />
<blockquote><a href="http://forum.synology.com/wiki/index.php/How_to_manage_the_MySQL_database_using_phpMyAdmin">http://forum.synology.com/wiki/index.php/How_to_manage_the_MySQL_database_using_phpMyAdmin</a><br />
(unzip phpmyadmin into shared web. copy phpmyadmin\config.sample.inc.php into config.inc.php, and add these ''. then flag it as read only.<br />
go on http://diskstation/phpmyadmin<br />
in privileges:<br />
create user in mysql db<br />
check 'create database for user + all credentials'</blockquote><b> Install 'Ruby and the gems'</b><br />
<blockquote style="font-family: "Courier New",Courier,monospace;">ipkg install rubygems</blockquote> <b>Install the right version of Rake and Rails</b> (long process => coffee time):<br />
<blockquote style="font-family: "Courier New",Courier,monospace;">gem install rails -v 2.3.5<br />
gem install rack -v 1.0.1</blockquote> <b>Plug Ruby with MySQL</b>, using an adapter:<br />
<blockquote style="font-family: "Courier New",Courier,monospace;">cd /tmp<br />
check http://github.com/tmtm/ruby-mysql/downloads<br />
wget http://github.com/downloads/tmtm/ruby-mysql/ruby-mysql-2.9.3-beta.tar.gz<br />
tar -xzvf ruby-mysql-2.9.3-beta.tar.gz<br />
cd ruby-mysql-2.9.3-beta/<br />
ruby setup.rb</blockquote> <b>Download and configure Redmine</b> (<a href="http://www.redmine.org/wiki/redmine/RedmineInstall">http://www.redmine.org/wiki/redmine/RedmineInstall</a>)<br />
<blockquote style="font-family: "Courier New",Courier,monospace;">mkdir /volume1/apps/<br />
cd /volume1/apps<br />
wget http://rubyforge.org/frs/download.php/72201/redmine-1.0.1.tar.gz<br />
tar -xzvf redmine-1.0.1.tar.gz</blockquote><blockquote><span style="font-family: "Courier New",Courier,monospace;">mv redmine-1.0.1 redmine</span></blockquote><blockquote style="font-family: "Courier New",Courier,monospace;">chown -R nobody:users redmine/<code></code></blockquote><blockquote style="font-family: "Courier New",Courier,monospace;">cp config/database.yml.sample config/database.yml<br />
nano config/database.yml <br />
(enter MySQL credential) </blockquote><b> Session Key creation & Database init </b><br />
<blockquote><code>RAILS_ENV=production rake config/initializers/session_store.rb</code><code></code></blockquote><blockquote><code>RAILS_ENV=production rake db:migrate</code></blockquote> <b>You should be able to launch Redmine</b> from this point, with the command line.<br />
<blockquote style="font-family: "Courier New",Courier,monospace;">ruby /volume1/apps/redmine/script/server -e production</blockquote> <b>Create a startup script</b>, daemonizing redmine:<br />
<blockquote style="font-family: "Courier New",Courier,monospace;">nano /opt/etc/init.d/S97rubyrails.sh</blockquote><blockquote style="font-family: "Courier New",Courier,monospace;">#!/bin/ash<br />
case "$1" in<br />
start)<br />
/opt/bin/ruby /volume1/rubyapps/redmine/script/server webrick -d -e production<br />
;;<br />
stop)<br />
killall ruby<br />
;;<br />
restart)<br />
$0 stop<br />
sleep 1<br />
$0 start<br />
;;<br />
*)<br />
echo “usage: $0 { start | stop | restart}” &>2<br />
exit 1<br />
;;<br />
esac</blockquote><blockquote>don't forget to <span style="font-family: "Courier New",Courier,monospace;">chmod 755 S97rubyrails.sh </span></blockquote> <b>Now, </b>y<b>ou can access redmine via <u>http://synology:3000</u></b> .<br />
<blockquote>But Let's go one step further by implementing a proxy within Apache. The proxy thing helps if you need access to your redmine setup through the default syno apache frontend: it makes sense when you're enforcing security with passwords (Apache style), or only want to open your 80 port in your firewall.</blockquote><br />
<b>Finally, Reverse Proxying with Apache</b>:<br />
<br />
Add this to /usr/syno/apache/conf/httpd.conf-user<br />
<blockquote style="font-family: "Courier New",Courier,monospace;">LoadModule proxy_module modules/mod_proxy.so<br />
LoadModule proxy_http_module modules/mod_proxy_http.so<br />
ProxyRequests Off<br />
ProxyPreserveHost On<br />
ProxyPass /redmine/ http://127.0.0.1:3000/<br />
ProxyPassReverse /redmine/ http://127.0.0.1:3000/</blockquote><b>Apache server restart</b><br />
<blockquote style="font-family: "Courier New",Courier,monospace;">/usr/syno/etc.defaults/rc.d/S97apache-user.sh restart</blockquote> <b>And</b> finally the most important part: <b>tell Redmine to prefix every url with a 'redmine/'</b>when generating pages:<br />
<blockquote>Add the following line at the end of your Redmine config/environment.rb</blockquote><blockquote style="font-family: "Courier New",Courier,monospace;">Redmine::Utils::relative_url_root = "/redmine" </blockquote> <b>Done</b> ! Hopefully. Access to redmine via <b>http://synology.ip/redmine</b> <br />
<br />
<b>Final note</b>: after some time on using RedMine, i wouldn't recommend using it on a low-end synology. As an example, my DS-107+ really takes age at updating project wiki pages. In fact, i ended using the NAS as a gateway between the outside, and some other private servers running on my private network... Next post should about this.Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com10tag:blogger.com,1999:blog-3367830669483719981.post-29674648333492496802010-09-20T21:28:00.009+02:002011-01-10T09:58:06.599+01:00Mercurial on Synology (hg web)<span style="font-size: small;"></span><span style="font-size: small;"></span><br />
<div style="font-family: Verdana,sans-serif;"><br />
<span style="font-size: small;">I switched from a single Mercurial repository configuration (cf previous post) to one-per-project-so-multiple-repositories on my Synology.</span><br />
<div style="font-family: Verdana,sans-serif;"><br />
<span style="font-size: small;">All my projects would be stored on NAS, located under a specific directory <i>/volume1/repos , </i>and browsable through internet at http://diskstation/hg</span><br />
<br />
<span style="font-size: small;">I was using ssh until now but someone suggested an <b>hg web</b> configuration: </span><span style="font-size: small;">so, basically we are going to configure the native Apache web server to allow Mercurial transactions *and <b>repositories browsing</b>* via http/https.</span></div></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><br />
</span><br />
<span style="font-size: small;"> </span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;">This is how i did it, the 'minimal Apache fuss' way, dealing with a dedicated web directory via <i>.htaccess/.htpasswd</i> files: it's far from perfect, security speaking, as it does not follow every Apache recommendations. </span><br />
<span style="font-size: small;">Sorry, but i didn't want to cripple this How-To with too much external considerations.</span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><br />
</span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><b>1) Requirements:</b></span></div><ul><li><span style="font-family: "Verdana",sans-serif; font-size: small;">being able to telnet into your synology box</span></li>
</ul><ul><li><span style="font-family: "Verdana",sans-serif; font-size: small;">being able to ipkg packages</span></li>
</ul><ul><li><span style="font-family: "Verdana",sans-serif; font-size: small;">having mercurial installed</span></li>
</ul><ul><li><span style="font-family: "Verdana",sans-serif; font-size: small;">having nano installed, or mastering vi</span></li>
</ul><span style="font-family: "Verdana",sans-serif; font-size: small;"> (cf previous post)</span><br />
<div style="font-family: Verdana,sans-serif;"><br />
</div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><b>Note:</b></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">to edit text files, install nano with <span style="font-family: "Courier New","Courier",monospace;">ipkg install nano</span><b> </b></span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">if you're editing files into windows through shared directories (using pspad ?) dont forget to save files the unix way (CR). Or Apache will fail @ parsing them.</span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"></span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><b>2) Enable Web Service on Synology:</b></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">using synology control panel (<a href="http://diskstation:5000/">http://diskstation:5000</a>), </span><span style="font-size: small;">enable web services, and enable https </span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> Apache web service should now be 'live', and you should have a new 'web' shared directory in <i>/volume1/web</i> or </span><span style="font-size: small;"><i>/var/services/web (</i>both paths are identical<i>).</i></span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><br />
</span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><b>3) Creating a directory of Repositories (with correct credentials):</b></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">telnet into your diskstation, and type</span></li>
</ul></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> mkdir /volume1/repos/hg</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> chown -R nobody:users /volume1/repos </span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> hgweb/apache would have problems to access repos otherwise (<i style="font-family: "Courier New",Courier,monospace;">Error: abort: HTTP Error 500: Permission denied: .hg/store/lock</i>), as processes are spawned with <i>nobody:users</i> credentials (check this with '<span style="font-family: "Courier New","Courier",monospace;">ps</span>', looking at <span style="font-family: "Courier New","Courier",monospace;">httpd</span> processes group and user).</span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> could be good to create a <b>shared</b> <i>repos/</i> directory (via syno control panel).</span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">now create a <i>/volume1/repos/hg/test</i> repository, type : </span></li>
</ul></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> cd /volume1/repos/hg</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> hg init test</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> cd test</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> nano test.txt (write some and save)</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> hg add test.txt </span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> hg commit -u yourname -m first</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> </span></div><ul><li><span style="font-size: small;"><span style="font-family: "Verdana",sans-serif;">create a /volume1/<i>web/</i></span><i style="font-family: Verdana,sans-serif;">hg</i><span style="font-family: "Verdana",sans-serif;"> subdirectory </span></span></li>
</ul><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> cd /volume1/web </span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> mkdir hg</span><br />
<span style="font-size: small;"> </span><span style="font-size: small;"><br />
</span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><b>4) Time for Script and Config </b></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">create a <i>.htaccess</i> file to allow script executions in <i>/volume1/</i><i>web/hg/.htaccess</i></span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">cd /volume1/web/hg</span> (or <span style="font-family: "Courier New","Courier",monospace;">cd </span></span><span style="font-family: "Courier New","Courier",monospace; font-size: small;">/var/services/web</span><span style="font-size: small;"><span style="font-family: "Courier New","Courier",monospace;">/hg</span>)</span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">nano .htaccess</span></span><br />
<br />
<span style="font-size: small;"><i> </i> (.htaccess is an Apache config file specifying options for this specific directory</span><span style="font-size: small;">) </span><br />
<ul><li><span style="font-size: small;">insert this:</span></li>
</ul><blockquote style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><i>AddHandler cgi-script .cgi<br />
Options +FollowSymLinks +ExecCGI <br />
<br />
AuthUserFile /var/services/web/hg/.htpasswd<br />
AuthName "Protected Access"<br />
AuthType Basic<br />
<br />
R<limit get="" post="">equire valid-user<br />
</limit> </i></span></blockquote><span style="font-size: small;"> In this directory, Apache is allowed to execute cgi scripts and will protect access with login/passwords. If you don't want a password protected directory, erase all but the two first lines.</span><br />
<span style="font-size: small;"> Then, to password access <i>/volume1/web/hg/</i>: </span><br />
<ul><li><span style="font-size: small;">create a <i>.htpasswd</i> file in <i>/volume1/web/hg/ </i>to store login info<i><br />
</i></span></li>
</ul><span style="font-size: small;"><span style="font-family: "Courier New","Courier",monospace;"> cd /volume1/web/hg</span> <span style="font-family: "Courier New","Courier",monospace;"><br />
</span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New","Courier",monospace;"> nano .htpasswd</span></span><br />
<ul><li><span style="font-size: small;">insert login:crypted_password entries (such as <i>johndoe:ES7PtTtC.vd8E</i>) for each user you need an access for. As Synology does not embed <i>htpasswd </i>command, use <a href="http://www.xs4all.nl/%7Eremcovz/htpasswd.html">http://www.xs4all.nl/~remcovz/htpasswd.html</a> to generate them. </span>For those who do not trust websites that generate passwords (like Mike) download the htpasswd generator form apachefriends inside xampp apache bin bundle <span class="Object" id="OBJ_PREFIX_DWT65"><span class="Object" id="OBJ_PREFIX_DWT66"><a href="http://sourceforge.net/projects/xampp/files/" target="_blank">http://sourceforge.net/projects/xampp/files/</a></span></span> <span style="font-size: small;">(thx Mike).</span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> now, get and modify the Mercurial web cgi script (into <i>/volume1/web/hg)</i></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">get mercurial <i>hgweb.cgi</i> from <a href="http://www.selenic.com/repo/hg-stable/file/">there</a> or via </span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">cd /volume1/web/hg </span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New","Courier",monospace;"> wget http://www.selenic.com/repo/hg-stable/raw-file/7cf258b2d0cc/hgweb.cgi </span></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">rename it into <i>index.cgi</i></span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">mv hgweb.cgi index.cgi </span></span></div><ul><li><span style="font-size: small;"><span style="font-family: "Verdana",sans-serif;">flag this python script as executable, and assign credentials (thx anon)</span></span></li>
</ul><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">chmod u+x index.cgi</span> </span><br />
<span style="font-size: small;"> <span style="font-family: "Courier New",Courier,monospace;">chown -R nobody:users index.cgi</span> </span><span style="font-size: small;"><span style="font-family: "Courier New","Courier",monospace;"> </span></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">create a symbolic link to your favorite python executable: </span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">ln /opt/bin/python2.6 /opt/bin/python</span></span><span style="font-size: small;"><span style="font-family: "Courier New","Courier",monospace;"></span></span><br />
<ul><li><span style="font-size: small;">change <i>/volume1/web/hg/</i><i>index.cgi</i> first line to: </span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><i> </i></span><span style="font-family: "Courier New","Courier",monospace;"><span style="font-size: small;">#!/opt/bin/python </span></span><br />
<ul><li>change in index.cgi (thx Mike):</li>
</ul><blockquote>config = "/var/services/web/hg/hgweb.config"<span style="font-family: "Courier New","Courier",monospace;"><span style="font-size: small;"> </span></span></blockquote><ul><li><span style="font-size: small;">create hgweb config file in <i>/volume1/web/hg/hgweb.config</i></span></li>
</ul><span style="font-size: small;"><i> </i></span><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">nano /volume1/web/hg/hgweb.config </span></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">write</span></li>
</ul></div><blockquote style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">[collections]</span><br />
<span style="font-size: small;">/volume1/repos/hg = /volume1/repos/hg<span style="font-family: "Verdana",sans-serif;"></span></span></blockquote><blockquote style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Verdana",sans-serif;">this config file is parsed by <i>hgweb.cgi</i> (now <i>index.cgi</i>), and will allow it to scan the whole directory to build the repository list. They are other options to play with.</span></span></blockquote><span style="font-size: small;"><span style="font-family: "Verdana",sans-serif;"><b>5?) Optionally</b>, error feedbacks from Apache:</span></span><span style="font-size: small;"> </span><br />
<ul><li><span style="font-family: "Verdana",sans-serif; font-size: small;">edit apache config </span><i style="font-family: Verdana,sans-serif;"><span style="font-size: small;">/usr/syno/apache/conf/httpd.conf-user</span></i><span style="font-size: small;"> </span></li>
</ul><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">nano /usr/syno/apache/conf/httpd.conf-user</span></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">to get log informations, change the line</span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">ErrorLog /dev/null</span></span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> into</span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">ErrorLog /var/log/httpd-error-user.log</span></span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">save and restart apache <br />
</span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">/usr/syno/etc.defaults/rc.d/S97apache-user.sh restart </span></span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> </span></div><div style="font-family: Verdana,sans-serif;"><ul><li><span style="font-size: small;">then, to access apache log </span></li>
</ul></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> <span style="font-family: "Courier New","Courier",monospace;">cat /var/log/httpd-error-user.log|more</span></span></div><br />
<div style="font-family: Verdana,sans-serif;"><b><span style="font-size: small;">Final notes: </span></b></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> You should be able to browse your repos via </span><span style="font-size: small;"><a href="http://diskstation/hg/index.cgi/test">http://diskstation/hg</a></span><span style="font-size: small;">, <a href="http://diskstation/hg/index.cgi/test">http://diskstation/hg/index.cgi/test</a> or <a href="https://diskstation/hg/index.cgi/reposname">https://diskstation/hg/index.cgi/test</a></span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> Use the latter two to pull/push changes from/into other repos. </span><br />
<span style="font-size: small;"> Mercurial pushes are only allowed through https: it's possible to change this behavior in <i>hgweb.config</i>. Otherwise, dont forget to open your router to port 443 transactions. </span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"> And yes it's working: i'm using it every day<b> :)</b></span><b><span style="font-size: small;"><br />
</span></b></div><div style="font-family: Verdana,sans-serif;"> <span style="font-size: small;">With Redmine. Next post should be totally about RedMine.</span></div><div style="font-family: Verdana,sans-serif;"><br />
</div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><b>References:</b></span></div><div style="font-family: Verdana,sans-serif;"><a href="http://forum.synology.com/wiki/index.php/Using_the_Apache_web_page_access_controls"><span style="font-size: small;">http://forum.synology.com/wiki/index.php/Using_the_Apache_web_page_access_controls</span></a></div><div style="font-family: Verdana,sans-serif;"><a href="http://mercurial.selenic.com/wiki/HgWebDirStepByStep"><span style="font-size: small;">http://mercurial.selenic.com/wiki/HgWebDirStepByStep</span></a></div><div style="font-family: Verdana,sans-serif;"><a href="http://adminschoice.com/vi-editor-quick-reference"><span style="font-size: small;">http://adminschoice.com/vi-editor-quick-reference</span></a></div><div style="font-family: Verdana,sans-serif;"><a href="http://httpd.apache.org/docs/2.0/howto/htaccess.html"><span style="font-size: small;">http://httpd.apache.org/docs/2.0/howto/htaccess.html</span></a></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><br />
</span></div><span style="font-size: small;"><br />
</span><br />
<div style="font-family: Verdana,sans-serif;"><br />
</div>Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com9tag:blogger.com,1999:blog-3367830669483719981.post-85785579830406172832010-05-31T13:25:00.010+02:002010-06-01T10:56:07.130+02:00XML Parsing and IndexingOne of the idea behind GFE ([dje-fe], see previous post) is to be the less intrusive and the most reactive application. A front-end shouldnt need long processes stopping the user about to play, nor any private files written on disk (especially if you want it running from a DVD).<br />
But GFE needs to display informations about currently selected game (from a collection of 10000 items).<br />
Such data exists and is usually available through (big) xml files... They're generated by Mame.exe, or available from the Net (google 'dat file emulator').<br />
Hence the idea to parse like 40 Megs of xml data on the fly (at each run), and index/map the document to avoid keeping the whole file in memory.<br />
After two weeks studying the topic, it's time for conclusions :<br />
<ol><li>Microsoft Xml Pull Parser is fast. Written in .Net, but *correctly* written, it's generally a good tool for your xml needs. It's a pull system, easier to manipulate than SAX, and probably faster (look at <a href="http://msdn.microsoft.com/fr-fr/library/7hh47ty4%28v=VS.80%29.aspx" mce_href="http://msdn.microsoft.com/fr-fr/library/7hh47ty4%28v=VS.80%29.aspx" target="_blank" title="XmlTextReader">XmlTextReader</a> for reference). It takes 750 ms to walk 40 megs of data (8800 records) on my computer.</li>
<li>Unfortunately you can't bookmark the interesting parts of your document with it. We could rely on the line/character pair this parser is returning but then another text parser should extract text blocks from line/characters pairs. Maybe tricky to implement and we'll lose some horsepower in the process.</li>
<li>Note that parsing xml files is easy as long as we don't want document validation or xpath support: state machine only has to handle 10-12 token types, c# is silently handling various character format.</li>
</ol>So what ? Why not writing a dedicated indexing-xml-pull-parser ?<br />
Some results after a dozen hour of coding, a custom pull parsing implementation:<br />
<ol><li>It's now as fast as MS XmlTextReader: first version wasn't :) too much function calls is hitting very hard c# performance (8 times slower than the original !), solution is to pack the whole state machine into a single function: now it's easily indexing 50 Megs of xml per second.</li>
<li>It's able to give file stream position information about each element start and end: during some initialization pass, an indexer stores each record key and location values in a dictionnary, for further fast access.</li>
<li>When GFE needs a particular record info, the dictionnary is requested for the location of the fragment which is read from huge file, and loaded into memory to be thoroughly parsed. Apparently it's fast enough for 100 random requests per second. It's 100 times enough :)</li>
<li>there is no 4.</li>
</ol>This 'works' and fits a particular situation for a particular embedded application: no memory stress, no alien file creation. Currently it's only limited by a minimal support of character types (it's only handling ANSI+unicode).<br />
But definitely it looks like an achievable way to go if you feel somewhat embarassed with existing implementation.<br />
Below is the code source of the main state machine function: contact me for more implementation details.<br />
<pre class="brush: csharp">public TokenType Next(TokenType notifs)
{
_insideElement:
if (_currentType < TokenType.END_ELEMENT)
{
for (; ; )
{
//attribute
switch (_ioBuffer[_bufferIndex])
{
case ' ':
case '\t':
case '\r':
case '\n':
_bufferIndex++;
continue;
case '>': //end of start element
_bufferIndex++;
_depth++;
goto _beyondElement;
case '/': //empty element
_bufferIndex++;
if (_bufferIndex + 1 > _dataLen)
PrefetchIO(1);
if (_ioBuffer[_bufferIndex] == '>')
{
_bufferIndex++;
_tokenEndOffset = _bytesParsed + _bufferIndex;
_currentType = TokenType.END_ELEMENT; //EMPTY ELEMENT ! it starts and ends on the same token
if ((notifs & TokenType.END_ELEMENT) != 0)
return _currentType;
goto _beyondElement;
}
return DoExpected(">");
case '\0':
if (!FillIOBuffer())
return TokenType.END_OF_STREAM;
continue;
default:
_currentType = ProcessAttribute((notifs & TokenType.ATTRIBUTE) != 0);
if ((notifs & TokenType.ATTRIBUTE) != 0)
return _currentType;
continue;
}
}
}
//
//beyond element: data, or comment, or pi, cdata
_beyondElement:
for (; ; )
{
_start:
switch (_ioBuffer[_bufferIndex])
{
case ' ':
case '\t':
case '\r':
case '\n':
++_bufferIndex;
continue;
case '\0':
if (!FillIOBuffer())
return (_currentType = DoEndOfStream());
continue;
case '<':
_tokenStartOffset = _bytesParsed + _bufferIndex;
++_bufferIndex;
for (; ; )
{
switch (_ioBuffer[_bufferIndex])
{
case '!': //comment, cdata, doctype
_bufferIndex++;
if (_bufferIndex + 7 > _dataLen)
PrefetchIO(7);
if ((_ioBuffer[_bufferIndex] == '-') && (_ioBuffer[_bufferIndex + 1] == '-'))
{
_bufferIndex += 2;
ProcessComment();
goto _start;
}
if ((_ioBuffer[_bufferIndex] == '[') && (_ioBuffer[_bufferIndex + 1] == 'C') && (_ioBuffer[_bufferIndex + 2] == 'D') &&
(_ioBuffer[_bufferIndex + 3] == 'A') && (_ioBuffer[_bufferIndex + 4] == 'T') && (_ioBuffer[_bufferIndex + 5] == 'A') &&
(_ioBuffer[_bufferIndex + 6] == '['))
{
_bufferIndex += 7;
ProcessCData();
goto _start;
}
if ((_ioBuffer[_bufferIndex] == 'D') && (_ioBuffer[_bufferIndex + 1] == 'O') && (_ioBuffer[_bufferIndex + 2] == 'C') &&
(_ioBuffer[_bufferIndex + 3] == 'T') && (_ioBuffer[_bufferIndex + 4] == 'Y') && (_ioBuffer[_bufferIndex + 5] == 'P') &&
(_ioBuffer[_bufferIndex + 6] == 'E'))
{
_bufferIndex += 7;
ProcessDocType();
goto _start;
}
return DoUnexpected("-");
case '?': //pi
_bufferIndex++;
ProcessPI();
goto _start;
case '\0':
//--- fill data
if (!FillIOBuffer())
return (_currentType = TokenType.END_OF_STREAM);
continue;
case '/': //end element
_bufferIndex++;
_currentType = ProcessEndElement((notifs & TokenType.END_ELEMENT) != 0);
if ((notifs & TokenType.END_ELEMENT) != 0)
return _currentType;
goto _start;
default: //new element
//(notifs & TokenType.START_ELEMENT) != 0);
_currentType = ProcessStartElement(true);//always in full as element name may is extremely usefull to get
if ((notifs & TokenType.START_ELEMENT) != 0)
return _currentType;
goto _insideElement;
}
}
default: //element data. (probably.)
_currentType = ProcessData((notifs & TokenType.DATA) != 0);
if ((notifs & TokenType.DATA) != 0)
return _currentType;
goto _start;
}
}
}
</pre>Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-26774882109213573622010-05-11T20:33:00.004+02:002010-12-31T18:16:48.730+01:00GFE: Game FrontEnd (emu frontend)Hey,<br />
<br />
I spent the last months fighting/juggling/coding with WPF. Not the easiest hobby in town, should i mention, anyway: this is <b>GFE</b>.<br />
<br />
The idea behind the project is to be able to... Play. No fuss, and more generally minimal settings, to be able to list and launch a vast collection of games: emulated, freeware, flash, choice is vast.<br />
<br />
Basically <b>GFE</b> is listing a directory of... things (roms, zip, pics, you tell), probably thousands of them.<br />
<br />
Background scanners are trying to match every entry with snapshots and movies (furtherly stats and extra infos from web). And apart from primary enumeration, everything else is asynchronous for a smoother experience. <br />
<br />
All settings are guessed from a directory structure passed as application argument or preferably from a <i>gameinfo.xml</i> file.<br />
<br />
It's using low level inputs, preferably a joystick, enabling some interaction with <b>GFE </b>running in the background. And it's a WPF project: so all the frontend rendering is done through DirectX and accelerated hardware if available. <br />
<br />
OK now, this is the very first version of <b>GFE</b>, and, well: it's usable, but probably not versatile or cute enough. I'm working on that: you can help with suggestions, money, or simple greetings.<br />
<br />
Binary: <a href="http://alimbourg.free.fr/GFE-0.5.0.zip">GFE-0.5.0.zip</a> (45 Ko)<br />
Technical details:<br />
Windows - .NET 3.5, works on XP and Seven <br />
Joystick (XInput compatible) or Keyboard<br />
How to run it: <br />
Modify included GameInfo.xml and use it as the application parameter.<br />
Note: when in background, both LB+RB button (Ctrl+Back) is killing launched app and bring back <b>GFE </b>to front. LB+Y exits <b>GFE</b>.<br />
<br />
alimbourg at gmail.com for any question.<br />
<br />
This is <b>GFE </b>Emu FrontEnd (yes it's all animated, and video is playing from the selected game):<br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigjTqKuTXFstXwyO6ZWVjpeA-zNbjvJyPYwv38IaMiuM9V57GgRcVrgRDMNgty6w-zRLZ9s0dPx_YUojoUXAVCA4WVzyUEoW-bcI2zCsJNz2Uxurssx1Cj3_HlejrtwN8zwbNTLxV8CBA/s1600/GFE.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigjTqKuTXFstXwyO6ZWVjpeA-zNbjvJyPYwv38IaMiuM9V57GgRcVrgRDMNgty6w-zRLZ9s0dPx_YUojoUXAVCA4WVzyUEoW-bcI2zCsJNz2Uxurssx1Cj3_HlejrtwN8zwbNTLxV8CBA/s640/GFE.png" width="640" /></a></div>Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-69888792899196118492009-08-25T22:37:00.017+02:002010-10-17T15:36:07.198+02:00Mercurial on SynologyFirst telnet, and boostrap to install ipkg, classic (look at <a href="http://forum.synology.com/wiki/index.php/Modifications">this</a> and uses <a href="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/download.html">this</a>).<br />
<br />
Then <code>ipkg install py26-mercurial</code> (many mercurial flavours in repository btw: one for every major python version).<br />
<br />
Now mercurial should be installed somewhere in '/opt/bin' (which redirects to '/volume1/@optware/bin'), type <code>hg -v</code> to check this (or maybe <code>hg-2.6 -v</code> as ipkg apparently let me do the symbolic link: <code>ln /opt/bin/hg /opt/bin/hg-2.6</code>).<br />
<br />
You need to have some directory ready to hold a code repository, e.g. '//volume1/repos', executing <code>hg init /volume1/repos/testhg</code> will init/create a mercurial dir with (hidden) management files in it. <br />
<br />
We could start working in this, as a shared folder on the network (\\diskstation\repos\testhg), or via http (execute <code>cd /volume1/repos/testhg</code>, and <code>hg serv</code>, it mounts an http server on port 8000, accessible via 'http://192.168.0.X:8000' !), or via ssh (through 'ssh://user@192.168.0.x//volume1/repos/testhg') ! So Nice !<br />
<br />
I finally choosed the ssh way, to easily secure transaction.<br />
<br />
So, now <code>ssh</code> on synology: <br />
<br />
Let's activate the service using the web interface. <br />
Test it using <b>kitty</b> or <b>plink</b> with: <code>plink.exe -ssh -2 root@192.168.0.X "set"</code> should print a lot of variables contents.<br />
<br />
But, if we execute <code>plink.exe -ssh -2 root@192.168.0.X "hg"</code>: it should fail with <code>ash: hg: not found</code>. When the ssh daemon starts a session, it uses only a subset of the usual user environment, so our PATH variable is missing directories, hence cant find <b>hg</b>.<br />
<br />
We might override this by editing (vi) <code>/etc/ssh/sshd_config</code> on the synology, to set <code>PermitUserEnvironment yes</code>. <br />
(to restart the ssh daemon after this, type <code>killall sshd</code> and <code>/usr/syno/etc.defaults/rc.d/S95sshd.sh start</code>)<br />
This script mod triggers the execution of a script <code>$HOME/.ssh/environment</code> for each ssh session creation: let's create such (executable) script with the line <code>PATH=/opt/bin:/opt/sbin:$PATH</code> in it. <br />
<br />
Now back to plink: we should now be able to execute <code>hg</code> through ssh.<br />
<br />
And... Everything should roll from this point :)<br />
<br />
(Once in a while, telnet into your box (putty) and <code>ipkg update</code> and <code>ipkg upgrade</code>)Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com11tag:blogger.com,1999:blog-3367830669483719981.post-62269311416816845862009-07-31T09:15:00.002+02:002010-12-31T18:17:57.313+01:00Obese debug information (sqlite and qtcreator)SQLite.c is the 'amalgemon' version of the Database: a huge .c file containing all the dependencies to compile SQLite into our projects.<br />
<br />
Using GCC, and standard mingw compilation option, we probably all notice the ton of compilation warning telling us that debug infos are too huge to be handled correctly (if you tried that, it's impossible to trace sqlite sources with gdb).<br />
<div style="margin: 0; text-indent: 0;">The problem is concerning the embedded debugging information in STABS format: GCC is handling more modern types of debugging info. We just have to tell it to use them (<a href="http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html" target="_blank">http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html</a>)</div><br />
<br />
in your .pro file (assuming you're using QtCreator), force these flags to be used:<br />
<code><br />
#remove standard debug generation for c files<br />
QMAKE_CFLAGS_DEBUG -= -g<br />
#(*= 'if not present'), force uber debug infos, perfect for gdb<br />
QMAKE_CFLAGS_DEBUG *= -ggdb<br />
</code><br />
<br />
No more compilation warning=quickest compilation, and we're now able to trace sqlite.c in gdb... Another win ;-)Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-4832520519334769452009-07-31T09:08:00.009+02:002010-10-13T16:06:55.808+02:00Mame 132 and automated avi creation<div style="font-family: Verdana,sans-serif;">This is an How-To build a special mame.exe, wich allows some automation from AutoIt.</div><div style="font-family: Verdana,sans-serif;"><br />
</div><div style="font-family: Verdana,sans-serif;">I needed to find a way to send keys inputs which would trigger AVI recording of my games: but as Mame is using 'raw inputs', it cant be fooled with standard windows messages injection</div><div style="font-family: Verdana,sans-serif;"><br />
</div><div style="font-family: Verdana,sans-serif;">Fortunately the Mame project is really really (really) easy to modify and build, so i patched some sources to allow that.</div><div style="font-family: Verdana,sans-serif;"><br />
</div><div style="font-family: Verdana,sans-serif;">First, go there and follow every steps: <a href="http://mamedev.org/tools/">http://mamedev.org/tools/<br />
</a></div><div style="font-family: Verdana,sans-serif;"><br />
</div><div style="font-family: Verdana,sans-serif;">Once you get your first build, modify some sources:</div><div style="font-family: Verdana,sans-serif;"><br />
</div><div style="font-family: Verdana,sans-serif;">Add More Windows Message to allow events from the outside:<br />
</div><script type="syntaxhighlighter" class="brush: js"><![CDATA[
//pre-declared somewhere in windows.c:
void rawinput_keyboard_fake_update(int dik_code, int pressed);
//in windows.c/winwindow_video_window_proc, around line 1361
case WM_USER+10:
if (lparam&0x80) MessageBeep(0);
rawinput_keyboard_fake_update(wparam, lparam);
break;
case WM_USER+11:
if (!video_mng_is_movie_active(window->machine))
{
const char* filename = NULL;
if (lparam!=0)
filename = options_get_string(mame_options(), OPTION_MNGWRITE);
//video_mng_begin_recording(machine, NULL);
video_avi_begin_recording(window->machine, filename);
popmessage("REC START");
}
else
{
//video_mng_end_recording(machine);
video_avi_end_recording(window->machine);
popmessage("REC STOP");
}
break;
]]></script><br />
<div style="font-family: Verdana,sans-serif;">Augment raw inputs with incoming windows messages:<br />
</div><script type="syntaxhighlighter" class="brush: js"><![CDATA[
//in input.c, around line 1964, before rawinput_keyboard_update
//
void rawinput_keyboard_fake_update(int dik_code, int pressed)
{
device_info *devinfo;
for (devinfo = keyboard_list; devinfo != NULL; devinfo = devinfo->next)
if (devinfo->rawinput.device != NULL)
{
devinfo->keyboard.state[dik_code] = pressed?0x80:0x00;
}
}
]]></script><br />
<div style="font-family: Verdana,sans-serif;">Build it and voila. You should have a brand new mame.exe, listening for your external messages.</div><div style="font-family: Verdana,sans-serif;">I have such a binary build available for willing people.</div><div style="font-family: Verdana,sans-serif;">Next post should be an explanation for the whole Mame Avi Move Maker build with AutoIt...</div><div style="font-family: Verdana,sans-serif;">Regards (and eventually leave comments)</div>Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-7068713184540353352009-07-30T21:17:00.007+02:002009-08-12T10:21:20.268+02:00Clutter 1.0.0: Win32/MinGW (updated)Personal Hack for a win32 build of clutter-1.0.0 libraries.<br /><ul><li>static libraries,</li><li>interactive.exe and the whole dll package (glib, pango, etc),</li><li>and a configuration package (prebuild.zip)</li></ul><a href="http://alimbourg.free.fr/clutter-1.0.0">In there.</a><br />Basically all you need is:<br /><br />Get Code::Blocks/QtCreator whatever (but a Mingw flavor): <a href="http://www.codeblocks.org/downloads/5">http://www.codeblocks.org/downloads/5<br /></a><br />Get Clutter-1.0.0, and unzip-it somewhere on your hdd: <a href="http://www.clutter-project.org/sources/clutter/1.0/">http://www.clutter-project.org/sources/clutter/1.0/</a><br />Get GTK dependencies from <a href="http://www.gtk.org/download-windows.html">http://www.gtk.org/download-windows.html</a> (binaries+dev packages): pango, cairo, glib, gtk+<br />Get some other Mingw port from <a href="http://sourceforge.net/project/showfiles.php?group_id=7382">http://sourceforge.net/project/showfiles.php?group_id=7382</a> :<br />gettext, libiconv<br /><br />I put all those libraries side by side with clutter-1.0.0.<br /><br />Concerning mingw, it's likely that the package delivered with cb/qtcreator is outdated:<br />Get latest mingw API For MS Windows (<a href="http://sourceforge.net/projects/mingw/files/">http://sourceforge.net/projects/mingw/files/</a> , dev version) and unzip it into your mingw directory<br />Get latest glext.h (<a href="http://www.opengl.org/registry/api/glext.h">http://www.opengl.org/registry/api/glext.h</a>), to update your probably old \mingw\include\GL\GLext.h.<br /><br />Now some autoconf stuff:<br /><br />Get And Unzip prebuild.zip (<a href="http://alimbourg.free.fr/clutter-1.0.0">http://alimbourg.free.fr/clutter-1.0.0</a>) into clutter-1.0.0/build/<br />It will create some qtcreator\ dir as it's my primary develoment platform, but rename it at will.<br />The configuration package uses perl (i'm using tinyperl, included in archive) to autoconfigure clutter build, generate marshaling info and glib-enum-typing header files. It makes it ready to compile.<br />Edit configure.pl to match your installation directories as it needs GLIB for some prebuild steps.<br />Then, execute configure.bat.<br /><br />(Finally, it tweaks some qtcreator .pro project files to list every needed source files all the content from clutter\, clutter\COGL, clutter\Pango, clutter\json, clutter\win32: this, of course, has to be done 'by hand' for the other tools)<br /><br />It's now ready to compile...Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com4tag:blogger.com,1999:blog-3367830669483719981.post-46500777721072718242009-05-27T11:41:00.007+02:002010-12-31T18:16:21.238+01:00QtCreator Debug Helper...<span style="font-size: 85%;"><span style="font-family: verdana;">QtCreator (1.1 for now) is great tool to work with...</span><br />
<br />
<span style="font-family: verdana;">The whole Qt thing is, too.</span><br />
<br />
<span style="font-family: verdana;">I'm sharing some experience with the beast.</span><br />
<br />
<span style="font-family: verdana;">If you need some relevant debug infos concerning the Qt class guts, you need to instruct gdb on how to print them.</span><br />
<br />
<span style="font-family: verdana;">It's done via a 'debugging helper': some dll/plugin loaded by gdb on startup.</span><br />
<br />
<span style="font-family: verdana;">On my machine they didnt work without a rebuild after each Qt SDK every integration: </span><br />
</span><br />
<ul style="font-family: verdana;"><li><span style="font-size: 85%;"> go to Tools->Options...->Qt4->Qt Versions, </span></li>
<li><span style="font-size: 85%;"> check the active Qt SDK, and its path (QT_PATH).</span></li>
<li><span style="font-size: 85%;"> *</span><span style="font-size: 85%; font-weight: bold;">remove</span><span style="font-size: 85%;">* the whole *</span><span style="font-size: 85%; font-weight: bold;">QT_PATH/qtc-debugging-helper</span><span style="font-size: 85%;">* directory via explorer</span></li>
<li><span style="font-size: 85%;"> back to the Options Pane, select the active SDK, and press *Rebuild*</span></li>
<li><span style="font-size: 85%;"> go to Options->Debugger->Debugging Helper, check 'Use debugging helper', uncheck 'Use debugging helper from custom location'</span></li>
<li><span style="font-size: 85%;"> next time you debug your qt app, you should get some '43 custom... loaded' from gdb</span></li>
</ul>Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-60216955348390402632009-04-13T08:56:00.011+02:002010-12-31T18:17:15.425+01:00Cool Dialog GUI (9 quads method)<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVxE21315Wsg0EoXBMUZCH3NIcVRaooSIfsIxwThsZAwDePQlmRwZ7FeyX-3M8H1sulJCTcMvhatbWa_3lHvwMoZ4-Ub4TkBAg4JYz6aet6HyOTOIX5CcunNYaer1n_kNsfzwu7OYIpxg/s1600-h/Dialog.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5324132796016145490" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVxE21315Wsg0EoXBMUZCH3NIcVRaooSIfsIxwThsZAwDePQlmRwZ7FeyX-3M8H1sulJCTcMvhatbWa_3lHvwMoZ4-Ub4TkBAg4JYz6aet6HyOTOIX5CcunNYaer1n_kNsfzwu7OYIpxg/s320/Dialog.jpg" style="cursor: pointer; float: right; height: 310px; margin: 0pt 0pt 10px 10px; width: 320px;" /></a><br />
<br />
Hey all,<br />
<br />
If you want to draw some cool looking rectangle/dialog:<br />
<br />
<br />
this is the 9 quads method using... Clutter.<br />
<br />
First we need some texture like this (256x256 icon):<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1T4SV4zy16GRtOTbnUnW-FaqQbm6g9hFEs8FWV9ayAWffINtwy8rqyasoeqCAM2fI9eop-GPptLaAyT3Abc0hXHnjPBYXAkF7HqtseSKWJHujiMPlzIhcXZwJDv_dGpXUfbaYnNUvLQg/s1600-h/test.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5324127701140781394" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1T4SV4zy16GRtOTbnUnW-FaqQbm6g9hFEs8FWV9ayAWffINtwy8rqyasoeqCAM2fI9eop-GPptLaAyT3Abc0hXHnjPBYXAkF7HqtseSKWJHujiMPlzIhcXZwJDv_dGpXUfbaYnNUvLQg/s200/test.png" style="cursor: pointer; float: right; height: 200px; margin: 0pt 0pt 10px 10px; width: 200px;" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
To be loaded with:<br />
<pre class="cpp" name="code">texture = cogl_texture_new_from_file (texPath, 10, COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ANY, NULL);</pre><br />
<br />
Then, some layout parameters (inner rectangle coordinates):<br />
<pre class="cpp" name="code">float framing[4]={108.0/256.0,50.0/256.0,200.0/256.0,147.0/256.0};</pre><br />
<br />
and a function which splits the texture into 9 quads, to stretch the whole thing smartly:<br />
<br />
<pre class="cpp" name="code">static void _cogl_9_rectangle (float x_1, float y_1, float x_2, float y_2,
float framing[4], CoglHandle texHandle)
{
float verts[12*9];
if (!cogl_is_texture(texHandle))
return;
cogl_set_source_texture (texHandle);
cogl_push_matrix ();
cogl_translate (x_1, y_1, 0);
float subrect[4];
float w = x_2-x_1;
float h = y_2-y_1;
//uniformly stretched
subrect[0]=w*dims[0];
subrect[1]=h*dims[1];
subrect[2]=w*dims[2];
subrect[3]=h*dims[3];
//and or preserving original texture dims
int tex_w = cogl_texture_get_width(texHandle);
int tex_h = cogl_texture_get_height(texHandle);
float value = tex_w*dims[0];
if (value<subrect[0]) subrect[0]=value;
value = tex_h*dims[1];
if (value<subrect[1]) subrect[1]=value;
value = w - tex_w*(1.0f-dims[2]);
if (value>subrect[2]) subrect[2]=value;
value = h - tex_h*(1.0f-dims[3]);
if (value>subrect[3]) subrect[3]=value;
//and the 9 quads
cogl_rectangle_with_texture_coords (0.0f, 0.0f, subrect[0], subrect[1],
0.0f, 0.0f, dims[0], dims[1]);
cogl_rectangle_with_texture_coords (subrect[0], 0.0f, subrect[2], subrect[1],
dims[0], 0.0f, dims[2], dims[1]);
cogl_rectangle_with_texture_coords (subrect[2], 0.0f, w, subrect[1],
dims[2], 0.0f, 1.0f, dims[1]);
cogl_rectangle_with_texture_coords (0.0f, subrect[1], subrect[0], subrect[3],
0.0f, dims[1], dims[0], dims[3]);
cogl_rectangle_with_texture_coords (subrect[0], subrect[1], subrect[2], subrect[3],
dims[0], dims[1], dims[2], dims[3]);
cogl_rectangle_with_texture_coords (subrect[2], subrect[1], w, subrect[3],
dims[2], dims[1], 1.0f, dims[3]);
cogl_rectangle_with_texture_coords (0.0f, subrect[3], subrect[0], h,
0.0f, dims[3], dims[0], 1.0);
cogl_rectangle_with_texture_coords (subrect[0], subrect[3], subrect[2], h,
dims[0], dims[3], dims[2], 1.0);
cogl_rectangle_with_texture_coords (subrect[2], subrect[3], w, h,
dims[2], dims[3], 1.0f, 1.0);
cogl_pop_matrix();
}
</pre><br />
<br />
(<a href="http://code.google.com/p/syntaxhighlighter/">http://code.google.com/p/syntaxhighlighter</a>/ rocks)Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-70554198560094308052009-03-30T12:30:00.004+02:002009-03-30T12:51:43.566+02:00Clutter/Qt Creator IDE<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNGLgj-KeCopjsK9K-i8awxTah5bvzfvdRX0JlvEja8UmeDJcgie38Z-tYeU3mTGPSi1egHW5cX7DfraVXkF5pExKNzonpE_-Nipocwr6fhrFEwjJKnvUjE0hP6AP-_pu3n-LDhtpEGuE/s1600-h/ClutterQtCreator.jpg"><img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 320px; height: 220px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNGLgj-KeCopjsK9K-i8awxTah5bvzfvdRX0JlvEja8UmeDJcgie38Z-tYeU3mTGPSi1egHW5cX7DfraVXkF5pExKNzonpE_-Nipocwr6fhrFEwjJKnvUjE0hP6AP-_pu3n-LDhtpEGuE/s320/ClutterQtCreator.jpg" alt="" id="BLOGGER_PHOTO_ID_5318928647332013490" border="0" /></a>A new incomer into the free IDE arena: <span style="font-weight: bold;">QT Creator</span> from trolltech/nokia.<br /><br /><br /><br />The Windows version is based on the Mingw32 environment.... So Clutter is compilable with it.<br /><br /><br /><br /><a href="http://www.qtsoftware.com/downloads/sdk-windows-cpp">http://www.qtsoftware.com/downloads/sdk-windows-cpp</a><br /><br /><br />Very neat IDE. Provided to spread Qt4.5 all around the world, this IDE is included in the Qt SDK. Dont be afraid, you can use it to build your project without any Qt in them.<br /><br />To build Clutter(*) on Windows using this one: you need to follow the prebuild.bat step (see previous posts), to allow Clutter to be built under a minimalistic MinGW environment.<br /><br />And get the project file <a href="http://alimbourg.googlepages.com/Clutter.pro">Clutter.pro</a>, for use with QtCreator, to be modified for your needs.<br /><br />cheers<br /><br />(*: Nokia/Qt and Intel/Clutter are competitors concerning mobile frameworks... Kinda ironic to build one using the other)Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-44736348284186550932009-03-20T09:12:00.007+01:002009-03-20T13:33:56.399+01:00Win32 Clutter (0.9.2 and Bleeding edge) compilation...... Still using code::blocks:<br /><br />Okay i enhanced my scripts to make all this compiling with a native code::blocks install, but various clutter versions...<br /><br />Basically all you need is:<br /><br />- to get <span style="font-weight: bold;">Clutter</span> sources: using GIT repository (<span style="font-style: italic;">origin/master</span> branch fe), or here : <a href="http://www.clutter-project.org/sources/clutter/0.9/">http://www.clutter-project.org/sources/clutter/0.9/</a> (0.9.2)<br />- to create some %CLUTTER%\clutter\build\codeblocks directory<br />- to unzip in there, content of <a href="http://alimbourg.googlepages.com/codeblocks.zip">http://alimbourg.googlepages.com/codeblocks.zip</a><br />- to modify 'prebuild.bat' which configures various compilation defines, plus generates some .h/.c files using <span style="font-weight: bold;">glib</span> tools: so you have to change some paths to point your glib directory...<br />- run 'prebuild.bat': it will ask for <span style="font-style: italic;">perl.exe</span>,<span style="font-style: italic;"></span> but if you don't have it installed, will copy my own "clutter-enum-types.c/.h" (hence, should be out of sync at some point)<br /><br />Read <a href="http://www.clutter-project.org/blog/?p=68">http://www.clutter-project.org/blog/?p=68</a> for dependencies. See previous posts about how to get them.<br /><br />After that, everything should be ok for you to compile...<br /><br />For <span style="font-weight: bold;">Visual Studio Users</span>: all you have to do is to create .vcproj with all the source files... But probably that some typical gcc include files would be missing (i dont have visual right right now to check that) like <span style="font-style: italic;">libintl.h, iconv.h </span>(?).<br /><span style="font-style: italic;">gettext, libiconv</span> package for win32 are available <a href="http://sourceforge.net/project/showfiles.php?group_id=7382">here</a>, but i dont know how they integrate themselves into a <span style="font-style: italic;">visual studio</span> framework...<br /><br />PM or Comment if you need some more ;-).Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com6tag:blogger.com,1999:blog-3367830669483719981.post-6388144518984293002009-03-11T11:13:00.003+01:002010-12-31T18:17:35.462+01:00Clutter, 0.9 and above, places to look forBTW: for those interested in clutter 0.9.0 and above, i'm recommending using the test files as turorials as the other repo directories are still not very 0.9 friendly. And things did change a lot(!) between 0.8 and 0.9....<br />
<br />
Anyway, browsing <span style="font-style: italic;">clutter-xxx/tests/interactive</span> and <span style="font-style: italic;">clutter-xxx/tests/conform</span> directories should bring you with enough juice to start.<br />
<br />
Coming soon, some basic clutter code of mine.Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-88269650505670790772009-03-09T17:02:00.006+01:002009-03-11T11:12:02.816+01:00Bleeding Edge Clutter (Win32 build with C::B)<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrWurBYmabs-JxTna0UJhY3u4s0flGGNO7cNmTMj7kG8qzFx1OvXEWU9DKcKzRfP94Ub6enckuwiEvAYXVUgJGV06lsD7KD_HpRCMIaMuTa_D41VtSrsGyH9osQ7DmxnzShdNAkXYvH6A/s1600-h/clutter-snap.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 243px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrWurBYmabs-JxTna0UJhY3u4s0flGGNO7cNmTMj7kG8qzFx1OvXEWU9DKcKzRfP94Ub6enckuwiEvAYXVUgJGV06lsD7KD_HpRCMIaMuTa_D41VtSrsGyH9osQ7DmxnzShdNAkXYvH6A/s320/clutter-snap.jpg" alt="" id="BLOGGER_PHOTO_ID_5311222997991681266" border="0" /></a><br />Using GIT to retrieve repository:<br />GIT binaries here: <a href="http://code.google.com/p/msysgit/">http://code.google.com/p/msysgit/</a><br /><br /><ul><li>Start "Git GUI"</li><li>'Clone Depot'</li><li><span style="font-style: italic;">Source Depot</span> is <span style="font-style: italic;">git://git.clutter-project.org/clutter</span></li><li> <span style="font-style: italic;">Target</span> is yours: <span style="font-style: italic;">c:\Prog\clutter</span></li><li> Press 'Clone' and wait a while</li></ul><br /><br /><br />Thanks to them, they improved Win32 support :) No more dirty GL hacks to make it work.<br /><br />Get the latest CB files (see previous post about building Clutter on Win32): unzip this into your clutter\build\cb\: <a href="http://alimbourg.googlepages.com/cb-latest.zip">http://alimbourg.googlepages.com/cb-latest.zip</a><br /><br />Run <span style="font-style: italic;">prebuild.bat</span> and that's it. Open Code::Blocks and the workspace: everything should rock'n'roll...<br /><br />I'm doing some application tests to confirm my first impression: Clutter *is* pretty smart (even if i miss the 3rd dimension of OpenGL :|)<br /><br />Cheers,Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com0tag:blogger.com,1999:blog-3367830669483719981.post-75486077409029527102009-03-05T12:01:00.008+01:002010-12-31T18:15:40.990+01:00Clutter 0.9 (CodeBlocks/MinGW/Win32 build)<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhWJ6tIDH9Mc8QN5bhAosOG_g5hiVm0v2TQr0KRzeGCOiuYk0FqI_C97Vl3fEP69YCQ_sD1bkOwlbmT6ZIhs-6JKSSfushS65_bq6sCO80OGG6mVjsNYyR5U3O85PvbIwwPwVKNctsf7E/s1600-h/snap.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5309721713002781586" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhWJ6tIDH9Mc8QN5bhAosOG_g5hiVm0v2TQr0KRzeGCOiuYk0FqI_C97Vl3fEP69YCQ_sD1bkOwlbmT6ZIhs-6JKSSfushS65_bq6sCO80OGG6mVjsNYyR5U3O85PvbIwwPwVKNctsf7E/s200/snap.jpg" style="cursor: pointer; float: right; height: 134px; margin: 0pt 0pt 10px 10px; width: 215px;" /></a>Do you know <span style="font-weight: bold;">Clutter</span> ?<br />
<br />
"Clutter is an open source software library for creating fast, visually rich and animated graphical user interfaces. "<br />
<br />
<a href="http://www.clutter-project.org/">http://www.clutter-project.org/ </a><br />
<br />
Great Project. Really.<br />
<br />
A bit too much intricated with gnome/gtk, not really win32 native ;), not so much pictures to display about, but... Nice and Smart code: really promising architecture.<br />
Wanted to figure this on win32, as i'd like to create some click n play frontends for my htpc...<br />
Good news: it's buildable on Windows/CodeBlocks (mingw) with a bit of luck and elbow grease :)<br />
<br />
Here is a recipe:<br />
<br />
Get <span style="font-weight: bold;">Code::Blocks</span> (Mingw flavor): <a href="http://www.codeblocks.org/downloads/5">http://www.codeblocks.org/downloads/5</a><br />
<br />
Get<span style="font-weight: bold;"> </span><a href="http://www.clutter-project.org/sources/clutter/0.9/" style="font-weight: bold;">Clutter0.9</a>, and unzip-it somewhere on your hdd.<br />
<br />
Get GTK dependencies from <a href="http://www.gtk.org/download-windows.html">http://www.gtk.org/download-windows.html</a> (binaries+dev packages): <span style="font-weight: bold;">pango</span>, <span style="font-weight: bold;">cairo</span>, <span style="font-weight: bold;">glib</span>, <span style="font-weight: bold;">gtk+</span><br />
<br />
Get some Mingw port from <a href="http://sourceforge.net/project/showfiles.php?group_id=7382">http://sourceforge.net/project/showfiles.php?group_id=7382</a> :<br />
<span style="font-weight: bold;">gettext</span>, <span style="font-weight: bold;">libiconv</span><br />
<br />
I put all those libraries side by side with clutter-0.9.<br />
<br />
Now some OpenGL trickeries: this is the main problem when compiling on win32 as internal OGL support is only up to 1.2, and clutter is more 1.4. So, as usual, we'll play with extensions and runtime function pointers retrieval.<br />
Note that clutter/cogl is dealing with >1.4 extensions as well: mine is a hack concerning 'some functions 'between' OGL 1.2 and 1.4... So:<br />
<br />
Get latest <a href="http://www.opengl.org/registry/api/glext.h" style="font-weight: bold;">glext.h</a>, to update your probably old \codeblocks\mingw\include\GL\GLext.h.<br />
<br />
Create <span style="font-style: italic;">clutter-0.9.0\<span style="font-weight: bold;">build\cb</span></span> directory ('<span style="font-style: italic;">cb</span>' stands for <span style="font-style: italic;">code::blocks</span>, took the directory location from the old msvc_2k5 port).<br />
<br />
Unzip this patch/project <a href="http://alimbourg.googlepages.com/cb.zip" style="font-weight: bold;">archive file</a> in <span style="font-style: italic;">clutter-0.9.0\build\cb</span>.<br />
<br />
Run <span style="font-style: italic; font-weight: bold;">cb/prebuild.bat</span>: it will copy some config files, create the actor-marshall.h/.c, and replace some files with a patched version (have a look into <span style="font-style: italic; font-weight: bold;">prebuild.bat</span> as it probably wont fit with your directory configuration).<br />
<br />
Now open code::blocks and cb\clutter.workspace: you should be ready to compile and link both <span style="font-weight: bold;">clutter</span> and <span style="font-weight: bold;">interactive_d</span> projects.<br />
<br />
To execute <span style="font-style: italic;">interactive_d.exe</span>: you need a bunch of dll in the running directory as the content of clutter-0.9\test\data. This is my complete <a href="http://alimbourg.googlepages.com/Debug.zip">build folder</a>.<br />
<br />
<span style="font-style: italic;">interactive_d.exe</span> needs the name of the test to be ran, as a parameter, such as <span style="font-style: italic;">'interactive_d.exe </span><span style="font-style: italic;">test-clutter-cairo-flowers'</span>. Here is a two rows list of possible params:<br />
<code><br />
</code><br />
<div style="text-align: center;"><code>test-actor-clone test-actors</code><br />
<code>test-animation test-behave</code><br />
<code>test-binding-pool test-clip</code><br />
<code>test-clutter-cairo-flowers test-cogl-multitexture</code><br />
<code>test-cogl-offscreen test-cogl-primitives</code><br />
<code>test-cogl-tex-convert test-cogl-tex-foreign</code><br />
<code>test-cogl-tex-getset test-cogl-tex-polygon</code><br />
<code>test-cogl-tex-tile test-depth</code><br />
<code>test-easing test-events</code><br />
<code>test-fbo test-fullscreen</code><br />
<code>test-grab test-layout</code><br />
<code>test-main test-model</code><br />
<code>test-multistage test-offscreen</code><br />
<code>test-paint-wrapper test-perspective</code><br />
<code>test-pixmap test-project</code><br />
<code>test-random-text test-rotate</code><br />
<code>test-scale test-score</code><br />
<code>test-script test-shader</code><br />
<code>test-stage-read-pixels test-text-field</code><br />
<code>test-text test-texture-quality</code><br />
<code>test-textures test-threads</code><br />
<code>test-unproject test-viewport</code><br />
<br />
<div style="text-align: left;">That's it for Clutter 0.9 :)<br />
I'm going to dive more and more into it next days... And will publish my investigations in there. Stay tuned ?<br />
<br />
<br />
<br />
</div><code></code></div>Ashhttp://www.blogger.com/profile/01599236996988141745noreply@blogger.com3