Redmine with IronRuby (Windows)? - ruby-on-rails

Has anyone tried to run Redmine using IronRuby? Is it possible?

I think the answer is NO at present... doing a bit of google searching I found various
people asking a few trying and some raising issues...
https://serverfault.com/questions/165539/redmine-in-ironruby
Currently, Redmine is only supported on Ruby 1.8.6 and 1.8.7 and on Ruby Enterprise Edition. There are currently efforts ongoing to have Redmine running on jRuby and Rubinius. As there are not that many core devs running windows, I would not assume that anyone actively works on IronRuby compatibility.
If you are willing to help and code needed patches, you are welcome to speak up on http://redmine.org.
Redmine, yaml files can't have % in them..
In my fruitless efforts to get redmine running on IronRuby one of the things i discovered were that the lines like these: "field_done_ratio: % Done" in the locale yaml files throwed exceptions. if i removed the "%" it worked (or at least i went one step further).
(gave up after these 16hours, my last obstacle were infinite redirection while accessing localhost:3000/, although accessing localhost:3000/login went well, but after that you couldn't do anything.. )
http://ironruby.codeplex.com/workitem/list/basic?size=2147483647

I attempted to get Redmine running on IronRuby with some success a few months ago. The version of Redmine I used was 0.9.3, IronRuby version was 1.0v4, SQL Server 2005 and it was hosted from IIS 6. This was actually a lot of work to get it up and running. I had to make minor modifications to a bunch of Redmine files. I also added some files that were not present in my download like new_rails_defaults.rb. Additionally, I had to get the IronRuby source from GitHub and modify it slightly to get IronRack working.
To get IIS to work I had to redirected all traffic to .Net for processing in the Redmine IIS WebApplication I created. This was done through adding an application extension mapping to "C:\Windows\Microsoft.NET\Framework\v2.0.50727aspnet_isapi.dll"
I then redirected all traffic to IronRack in my Web.config file.
<httpHandlers>
<clear />
<add path="*" verb="*" type="IronRuby.Rack.HttpHandlerFactory, IronRuby.Rack"/></httpHandlers>
This stopped IIS from being able to serve static files. To fix this I created the StaticFileHttpHandler.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
namespace StaticFileHttpHandler
{
public class StaticFileHttpHandler : IHttpHandler
{
#region IHttpHandler Members
public bool IsReusable
{
get
{
return true;
}
}
public void ProcessRequest(HttpContext context)
{
string staticFileUrl = context.Request.Url.LocalPath.Replace(#"/", #"\");
string staticFilePath = context.Server.MapPath(#"~\..\..\");
string defaultStaticFilePathForRemapping = #"\Redmine\public";
string defaultRootDirectoryForRemapping = #"\Redmine";
bool remapImage = !string.IsNullOrWhiteSpace(context.Request.QueryString.ToString());
if (staticFilePath.EndsWith(#"\"))
{
staticFilePath = staticFilePath.Substring(0, staticFilePath.Length - 1);
}
if (remapImage)
{
staticFilePath += (defaultStaticFilePathForRemapping + staticFileUrl.Replace(defaultRootDirectoryForRemapping, ""));
}
else
{
staticFilePath += staticFileUrl;
}
if (File.Exists(staticFilePath))
{
context.Response.ContentType = GetMimeType(staticFilePath);
context.Response.TransmitFile(staticFilePath);
}
else
{
context.Response.ContentType = "text/plain";
context.Response.Write("The File Does Not Exist!!! File: " + staticFilePath);
}
context.Response.Flush();
context.ApplicationInstance.CompleteRequest();
}
// Found Here: http://kseesharp.blogspot.com/2008/04/c-get-mimetype-from-file-name.html
private string GetMimeType(string fileName)
{
string mimeType = "application/unknown";
string ext = System.IO.Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null)
{
mimeType = regKey.GetValue("Content Type").ToString();
}
return mimeType;
}
#endregion
}
}
This needs to be added to the httpHandlers section as well. And for every static file type you want to it to be able to serve. An example of serving a PNG file is show below.
<httpHandlers>
<clear />
<add path="*.png" verb="*" type="StaticFileHttpHandler.StaticFileHttpHandler, StaticFileHttpHandler"/>
<add path="*" verb="*" type="IronRuby.Rack.HttpHandlerFactory, IronRuby.Rack"/></httpHandlers>
I also needed to make an images_controller.rb file to point the static files at.
# This is a place holder controller to allow for mapping static images
class ImagesController < ApplicationController
def index
0
end
end
Next all *.yml files need double qoutes around values with the percent sign.
field_done_ratio: "% ???????"
Additionally, I had to comment out all index creation and deletion in the database setup files in the db\migrate folder.
In conclusion, it is possible to get Redmine mostly working with IronRuby, IronRack, IIS 6, and SQL Server 2005 but not without some modifications.

Related

Hangfire job on Console/Web App solution?

I'm new to Hangfire and I'm trying to understand how this works.
So I have a MVC 5 application and a Console application in the same solution. The console application is a simple one that just updates some data on the database (originally planned to use Windows Task Scheduler).
Where exactly do I install Hangfire? In the Web app or the console? Or should I convert the console into a class on the Web app?
If I understand it correctly, the console in your solution is acting like an "pseudo" HangFire, since like you said it does some database operations overtime and you plan to execute it using the Task Scheduler.
HangFire Overview
HangFire was design to do exactly what you want with your console app, but with a lot more of power and functionalities, so you avoid all the overhead of creating all that by yourself.
HangFire Instalation
HangFire is installed commonly alongside with ASP.NET Applications, but if you carefully read the docs, you will surprisingly find this:
Hangfire project consists of a couple of NuGet packages available on
NuGet Gallery site. Here is the list of basic packages you should know
about:
Hangfire – bootstrapper package that is intended to be installed only
for ASP.NET applications that uses SQL Server as a job storage. It
simply references to Hangfire.Core, Hangfire.SqlServer and
Microsoft.Owin.Host.SystemWeb packages.
Hangfire.Core – basic package
that contains all core components of Hangfire. It can be used in any
project type, including ASP.NET application, Windows Service, Console,
any OWIN-compatible web application, Azure Worker Role, etc.
As you can see, HangFire can be used in any type of project including console applications but you will need to manage and add all the libraries depending on what kind of job storage you will use. See more here:
Once HangFire is Installed you can configure it to use the dashboard, which is an interface where you can find all the information about your background jobs. In the company I work, we used HangFire several times with recurring jobs mostly to import users, synchronize information across applications and perform operations that would be costly to run during business hours, and the Dashboard proved to be very useful when we wanted to know if a certain job was running or not. It also uses CRON to schedule the operations.
A sample of we are using right now is:
Startup.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
//Get the connection string of the HangFire database
GlobalConfiguration.Configuration.UseSqlServerStorage(connection);
//Start HangFire Server and enable the Dashboard
app.UseHangfireDashboard();
app.UseHangfireServer();
//Start HangFire Recurring Jobs
HangfireServices.Instance.StartSendDetails();
HangfireServices.Instance.StartDeleteDetails();
}
}
HangfireServices.cs
public class HangfireServices
{
//.. dependency injection and other definitions
//ID of the Recurring JOBS
public static string SEND_SERVICE = "Send";
public static string DELETE_SERVICE = "Delete";
public void StartSend()
{
RecurringJob.AddOrUpdate(SEND_SERVICE, () =>
Business.Send(), //this is my class that does the actual process
HangFireConfiguration.Instance.SendCron.Record); //this is a simple class that reads an configuration CRON file
}
public void StartDeleteDetails()
{
RecurringJob.AddOrUpdate(DELETE_SERVICE, () =>
Business.SendDelete(), //this is my class that does the actual process
HangFireConfiguration.Instance.DeleteCron.Record); //this is a simple class that reads an configuration CRON file
}
}
HangFireConfiguration.cs
public sealed class HangFireConfiguration : ConfigurationSection
{
private static HangFireConfiguration _instance;
public static HangFireConfiguration Instance
{
get { return _instance ?? (_instance = (HangFireConfiguration)WebConfigurationManager.GetSection("hangfire")); }
}
[ConfigurationProperty("send_cron", IsRequired = true)]
public CronElements SendCron
{
get { return (CronElements)base["send_cron"]; }
set { base["send_cron"] = value; }
}
[ConfigurationProperty("delete_cron", IsRequired = true)]
public CronElements DeleteCron
{
get { return (CronElements)base["delete_cron"]; }
set { base["delete_cron"] = value; }
}
}
hangfire.config
<hangfire>
<send_cron record="0,15,30,45 * * * *"></send_cron>
<delete_cron record="0,15,30,45 * * * *"></delete_cron>
</hangfire>
The CRON expression above will run at 0,15,30,45 minutes every hour every day.
Web.config
<configSections>
<!-- Points to the HangFireConfiguration class -->
<section name="hangfire" type="MyProject.Configuration.HangFireConfiguration" />
</configSections>
<!-- Points to the .config file -->
<hangfire configSource="Configs\hangfire.config" />
Conclusion
Given the scenario you described, I would probably install HangFire in your ASP.NET MVC application and remove the console application, simple because it is one project less to worry about. Even though you can install it on a console application I would rather not follow that path because if you hit a brick wall (and you'll hit, trust me), chances are you'll find help mostly for cases where it was installed in ASP.NET applications.
No need of any more console application to update the database. You can use hangfire in your MVC application itself.
http://docs.hangfire.io/en/latest/configuration/index.html
After adding the hangfire configuration, you can make use of normal MVC method to do the console operations like updating the DB.
Based on your requirement you can use
BackgroundJob.Enqueue --> Immediate update to DB
BackgroundJob.Schedule --> Delayed update to DB
RecurringJob.AddOrUpdate --> Recurring update to DB like windows service.
Below is an example,
public class MyController : Controller
{
public void MyMVCMethod(int Id)
{
BackgroundJob.Enqueue(() => UpdateDB(Id));
}
public void UpdateDB(Id)
{
// Code to update the Database.
}
}

Can I set a single .NET MVC bundle to always be bundled (even in debug mode)?

I am using .LESS variables in my files. I have a LessTransform in my Bundler, which allows all my .less to see the variables. But when I turn bundling off, obviously it no longer works!
Can I see just a single bundle to always be bundled? (even when compilation debug=true)
Unfortunately it's an all or nothing setup (determined very early on by AssetManager.DeterminePathsToRender which, based on EnableOptimizations, either emits a bundle URL or individual script paths).
You could look into using the WebEssentials extension which handles .less (as well as other) files natively. At least then you'll be able to include the compiled version and let you move onto more important matters. Once you've finalized, you can bring bundling back into the equation.
I do not work on/for WebEssentials, I just find the extension very helpful
In the main application that I work with, we use the DotLess compiler directly to serve our stylesheets.
We store custom .LESS variables in the database and combine them with the .less file on the fly.
using System.Web.Mvc;
using dotless.Core;
using System.Web.Helpers;
public class SkinController : Controller
{
private const int TwentyMinutes = 1200;
[OutputCache(Duration = TwentyMinutes, VaryByParam = "*", VaryByContentEncoding = "gzip;deflate", VaryByCustom = "Scheme")]
public ActionResult Index()
{
string variablesFromDatabase = "these came from the database";
string lessFileContents = "this was read from the disk";
string content = Less.Parse(string.Concat(variablesFromDatabase, lessFileContents));
SetEtag(content);
return Content(content, "text/css");
}
private void SetEtag(string content)
{
string acceptEncoding = Request.Headers["Accept-Encoding"];
string value = string.Concat(content, acceptEncoding);
Response.AppendHeader("etag", string.Format("\"{0}\"", Crypto.Hash(value, "md5")));
}
}

Cloudfoundry: Images stored in database not displaying when app is running on cloudfoundy

I have a simple Grails application that is working fine when deployed to my local Tomcat server. However, when I deploy to Cloudfoundry the images saved to the database are not displaying. Googling about the solution has only revealed that on Cloudfoundry you cannot (or not supposed to) use the local file system to store image files but I am using the database and writing to main memory (output stream) in my controller. Anyone help.
Here is a portion of the code:
//Picture domain class
class Picture {
byte[] image
String mimeType
String name
static belongsTo = ...
static constraints = {
name(maxSize:20, )
image(maxSize:3145728)
....
}
String toString(){
...
}
}
//Picture controller
def image = {
def picture = Picture.get(params.id)
if(!picture || !picture.image){
...
}
else{
response.setContentType(picture.mimeType)
response.setContentLength(picture.image.size())
OutputStream out = response.getOutputStream();
out.write(picture.image);
out.flush();
out.close();
}
}
//In my gsp
< img width="128" height="96" class="image" src="${createLink(controller:'picture', action:'image', id:pictureInstance.ident())}" />
Thank you.
It seems that you are having troubles with your query. Why don't you change your db from postgreSql to MySQL and see if the problem still occurs. I don't believe the issue here is wit the RDBMS service.

Code-first always working with SQL Server Express or SQL Server CE

I'm building a MVC 3 application and use Entity Framework 4.3 code-first. My context is becoming complex so I've decided to working with SQL Server 2008 R2. Then I changed my connection string in web.config. I checked and I know the new connection string is correct, but EF is still working with the default connection string (.\SQLEXPRESS ...) from SQL Server CE (I have now deleted SQL Server CE from nuget packages).
My context name is CodeFirstContext and my connection string name is CodeFirstContext, too. But the return context.Products; always fails and/because the connection string in context says SQLEXPRESS (my web.config sets the connection string to SQLSERVER).
What is going on here? I erased all default connection strings in the project. When I am running the project, it still gets all data from SQL Server Express.
I have been searching for about two days. Why is this so difficult if so many people only have to change the connection string and then it works.
You might be picking up the connection string from your root/machine config, in your web.config file add a clear element like so
<connectionStrings>
<clear/>
.. your connection strings here
...
I 've solved the problem like that:
public class CodeFirstContext : DbContext
{
public CodeFirstContext() : base("RandevuIzle")
{
}
public DbSet<User> Users { get; set; }
}
<connectionStrings>
<add name="RandevuIzle" connectionString="Data Source=111.222.333.444\MSSQLSERVER2008; Initial Catalog=RandevuIzle;User Id=MyUserName;Password=myPassword" providerName="System.Data.SqlClient" />
Somethings went wrong but i cannot understand. I re-start the project after doing this code below. Then it's work normally.
As you instantiate your DbContext, are you providing a name that isn't CodeFirstContext?
Holy SQL Smoke, Batman! This drove me totally batty today. Getting EF 5.0 up and running w/ VS2010 on a new project was much more difficult than I imagined. I had the same problem and found this great Ode to the Code ::
http://odetocode.com/blogs/scott/archive/2012/08/15/a-troubleshooting-guide-for-entity-framework-connections-amp-migrations.aspx
And to be specific ::
public class DepartmentDb : DbContext
{
public DepartmentDb()
: base(#"data source=.;
initial catalog=departments;
integrated security=true")
{ }
public DbSet<Person> People { get; set; }
}
Got me the result I was needing. Do I think it's cool that I've got to set the data source like this and that it won't find the obvious solution within the app.config? No, I don't. But I have officially spent too much time attempting a transition from LINQ to SQL over to EF today and am going to go ahead and get some of the application done while I still have some interest in doing so.

Connection string for using SQL Server Compact with Entity Framework?

I'm done trying to Google for this. I have installed SQL Server CE 4.0, and have EF 4.1, but I can't get a proper connection string. Nothing on connectionstrings.com applies to me.
I just want to create a SqlCeEngine object, but no matter what I try I get some exception. Most recently it's been
Unknown connection option in connection string
with either "metadata", "app", "provider", or "provider connection string" after it. I know EF requires metadata in the connection string. And I can't imagine how anything could do without "provider connection string".
So far I have this:
<add name="DBContext"
connectionString="provider connection string="Data Source=MyDbFile.sdf;Persist Security Info=False;""
providerName="System.Data.EntityClient" />
At one point I had it with metadata:
<add name="DBContext"
connectionString="metadata=res://*/Data.DBContext.csdl|res://*/Data.DBContext.ssdl|res://*/Data.DBContext.msl;provider=System.Data.SqlClient;provider connection string="Data Source=MyDbFile.sdf;Persist Security Info=False;""
providerName="System.Data.EntityClient" />
Does it need metadata or not? What goes in the "app" part of the connection string? What should the provider be, System.Data.SqlClient or some SQL Server CE version? (which I still can't find when I try to add references. My add references window still only contains System.Data.SqlServerCe version 3.5.1.0.) Or nothing?
And what should go in the providerName attribute? Is System.Data.EntityClient correct? It's like there are 10 different variables here and every combination gives me a new equally mysterious error, none of which turns up anything useful on Google. I'm at my wits' end. Is this even possible?
You could try this in your App.config file (EF5 Code first migrations and SQL Server CE 4.0):
<connectionStrings>
<add name="DefaultConnection"
providerName="System.Data.SqlServerCe.4.0"
connectionString="Data Source=|DataDirectory|\Data\ProjectDb.sdf"/>
</connectionStrings>
And in you ProjectDb class:
class ProjectDb : DbContext
{
public ProjectDb()
: base("DefaultConnection")
{
}
}
It will work like a charm.
You can find more information here: http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-2-connections-and-models.aspx
I’d stuck with the same problem on Entity Framework 5.0 Code First approach with SQL Server Compact Edition 4.0
To solve it I pass instance of SqlCeConnection to DbContext's constructor:
public class Storage : DbContext
{
public Storage()
: base(new SqlCeConnection("Data Source=Database.sdf;Persist Security Info=False;"),
contextOwnsConnection: true)
{ }
//...
}
If you don’t want to inline connection string you could get it from App.config through ConfigurationManager
And of course you should add reference to the right version of System.Data.SqlServerCe (look inside Extentions tab in the Add Reference dialog)
This TechNet article outlines the steps for using EF with SQL Server Compact. This line jumped out at me, and may solve your problems:
make sure that provider=System.Data.SqlServerCe.3.5 in the connection
string.
(I would assume that you would want 4.0 instead of 3.5)
Give that a try and see how things go.
The Lu55's solution didn't work for me, but I found fow to fix it. To still use the automatic code generation (which can overwrite changes in a generated file), I added one more file with the following code:
using System.Data.Entity;
using System.Data.Objects;
namespace MyProject.Data
{
internal partial class Entities : DbContext
{
public Entities(string connectionString)
: base(
new ObjectContext(
#"metadata=res://*/Data.Model.csdl|
res://*/Data.Model.ssdl|
res://*/Data.Model.msl;
provider=System.Data.SqlServerCe.4.0;"),
true)
{
Database.Connection.ConnectionString = connectionString;
}
}
}
You have mixed a bit.
For SQL Server CE connection string can be quite easy (possibly replace DbContext with YourNameSpace.DbContextName):
<add name="DbContext"
connectionString="MyDbFile.sdf"
providerName="System.Data.SqlServerCe.4.0" />
I also had a lot of trouble with connections, so I did the following:
installed Entity Framework for SQL Server CE
Checked that web.config contains provider with invariant System.Data.SqlServerCe.4.0
Verified that there are NO string fields (which will be represented as columns in db) with length max or mode than 4000 symbols (to add restriction use annotation [MaxLength(4000)], by default == MAX)
Metadata are necessary when you use database-first model instead of code-first, so there is .edmx file which represents generated model of the database.

Resources