I'd like to add a file to a Redmine server without going through the graphical interface. I'm making the files available to the Redmine server by a separate svn checkout
process, so I just need to be able to add the files to Redmine's own database.
Ideally, I'd like a solution that could be run like this:
./redmine-register-file /path/to/my/file.ext "with optional description"
I believe the relevant part of the interface is found in redmine/apps/views/files/new.html.erb
. It's accessed by index.html.erb
, which has a small portion I believe is relevant:
<div class="contextual">
<%= link_to(l(:label_attachment_new), new_project_file_path(@project), :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %>
</div>
Here is the complete contents of new.html.erb
:
<h2><%=l(:label_attachment_new)%></h2>
<%= error_messages_for 'attachment' %>
<%= form_tag(project_files_path(@project), :multipart => true, :class => "tabular") do %>
<div class="box">
<% if @versions.any? %>
<p><label for="version_id"><%=l(:field_version)%></label>
<%= select_tag "version_id", content_tag('option', '') +
options_from_collection_for_select(@versions, "id", "name") %></p>
<% end %>
<p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
</div>
<%= submit_tag l(:button_add) %>
<% end %>
I don't know Ruby that well at all (anything beyond print name.reverse
is beyond me), but I know that all of those colons indicate selectors. What information can I glean from the standard interface that will help me in my task, and what might a complete solution look like?
Redmine uses a MySQL database to store its file registrations. The database is called redmine_production
, and uses the following schema:
mysql> SHOW COLUMNS FROM redmine_production.attachments;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| container_id | int(11) | YES | MUL | NULL | |
| container_type | varchar(30) | YES | | NULL | |
| filename | varchar(255) | NO | | | |
| disk_filename | varchar(255) | NO | | | |
| filesize | int(11) | NO | | 0 | |
| content_type | varchar(255) | YES | | | |
| digest | varchar(40) | NO | | | |
| downloads | int(11) | NO | | 0 | |
| author_id | int(11) | NO | MUL | 0 | |
| created_on | datetime | YES | MUL | NULL | |
| description | varchar(255) | YES | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)
Perhaps this will be of use: attachment.rb
For those who come by this by the Redmine thread I created: I tried to post the solution there as well, but the SPAM filter would not let me follow-up on the thread. It is probably because there was no intermediate response (*tear*).
It took a bit of time, but I figured it out. (I made a test instance of Redmine so as to not mess anything up with our production instance, so these values are default and should work for anybody trying to do this.)
A short synopsis of the process:
There is in fact no database validation going on, so even (2) is optional. As such, I won't go over how to get that information. (There are ample resources even on this site as to how to get this information.) The rest, however, requires a tiny bit of knowledge of how Redmine has its databases set up.
To start this, connect to your production MySQL database. (This is usually, if not always, redmine_production
. You can list all MySQL databases with the command SHOW DATABASES;
.)
Now, find the ID of your project you wish to add the file to. In the columns listing above, this will be inserted as container_id
.
mysql> SELECT * FROM projects;
+----+----------------+-------------+----------+-----------+-----------+---------------------+---------------------+----------------+--------+------+------+
| id | name | description | homepage | is_public | parent_id | created_on | updated_on | identifier | status | lft | rgt |
+----+----------------+-------------+----------+-----------+-----------+---------------------+---------------------+----------------+--------+------+------+
| 1 | git-helloworld | NULL | | 1 | NULL | 2012-01-01 13:00:00 | 2012-01-01 13:00:00 | git-helloworld | 1 | 1 | 2 |
| 2 | bzr-helloworld | NULL | | 1 | NULL | 2012-01-01 13:00:00 | 2012-01-01 13:00:00 | bzr-helloworld | 1 | 1 | 2 |
| 3 | hg-helloworld | NULL | | 1 | NULL | 2012-01-01 13:00:00 | 2012-01-01 13:00:00 | hg-helloworld | 1 | 1 | 2 |
| 4 | svn-helloworld | NULL | | 1 | NULL | 2012-01-01 13:00:00 | 2012-01-01 13:00:00 | svn-helloworld | 1 | 1 | 2 |
+----+----------------+-------------+----------+-----------+-----------+---------------------+---------------------+----------------+--------+------+------+
4 rows in set (0.00 sec)
In this example, we want to add the files to git-helloworld
, so our ID is 1
. So, to add a file to the database, we will execute the SQL command:
INSERT INTO attachments (container_id, container_type,
filename, disk_filename, digest) VALUES (
1, 'Project',
'Some File Name', 'file-name-on-disk', '0123456789abcdef');
A few notes about these fields:
container_id
: The ID of the project you wish to include the file incontainer_type
: The type of container this is; for this purpose, it is always Project
filename
: The string to display as the file namedisk_filename
: The actual path of the file, relative to /var/www/redmine/files/
digest
: A string representing the MD5 checksum of the file.Some not required, but recommended fields:
filesize
: The size of the file as an integer. I assume this is meant to be in bytes or kilobytes, but I don't know if it matters.author_id
: A user to associate the file with. For my purposes, I'm going to use admin
. Note that you can get a full list of Redmine users with SELECT * FROM users;
.description
: A file description. (This is the same optional description used in the interface.)content_type
: I would assume this is a MIME content type.created_on
: The date this file was created on.For the explicit types of all of these, refer to the columns listing in the original post.
Next, ensure that the path in disk_filename
actually exists relative to your redmine/files/
directory. (Note this means that you can actually organize it!) You don't have to do this, but you will obviously get a 404 if the file isn't there.
After that, you should be good to go!
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加