Как программно зарегистрировать файл в Redmine?

920
Sean Allred

Я хотел бы добавить файл на сервер Redmine без прохождения через графический интерфейс. Я делаю файлы доступными для сервера Redmine отдельным svn checkoutпроцессом, поэтому мне просто нужно иметь возможность добавлять файлы в собственную базу данных Redmine.

В идеале, я хотел бы, чтобы решение, которое могло быть выполнено следующим образом:

./redmine-register-file /path/to/my/file.ext "with optional description" 

Я считаю, что соответствующая часть интерфейса находится в redmine/apps/views/files/new.html.erb. Доступ к нему index.html.erb, у которого есть небольшая часть, я считаю, имеет отношение:

<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> 

Вот полное содержание 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 %> 

Я не знаю, Руби, что хорошо на всех (что - нибудь за print name.reverseэто за меня), но я знаю, что все эти двоеточия указывают селекторы. Какую информацию я могу почерпнуть из стандартного интерфейса, который поможет мне в моей задаче, и как может выглядеть законченное решение?


Ближе к решению:

Redmine использует базу данных MySQL для хранения своих регистраций файлов. База данных вызывается redmine_productionи использует следующую схему:

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) 

Еще немного Ruby источник

Возможно, это будет полезно: attachment.rb

1

1 ответ на вопрос

1
Sean Allred

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:

  1. Find the internal ID of the project you wish to add the files to.
  2. Determine file statistics.
  3. Insert file into database.

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 in
  • container_type: The type of container this is; for this purpose, it is always Project
  • filename: The string to display as the file name
  • disk_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!

proof

Похожие вопросы