Skip to content

Commit

Permalink
Better news display. Adds news cache
Browse files Browse the repository at this point in the history
  • Loading branch information
noidexe committed May 19, 2022
1 parent b73c729 commit da9b523
Show file tree
Hide file tree
Showing 5 changed files with 1,703 additions and 1,591 deletions.
2 changes: 1 addition & 1 deletion project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ config/windows_native_icon="res://windows_icon.ico"

[display]

window/size/width=900
window/size/width=1066
window/energy_saving/keep_screen_on=false

[network]
Expand Down
3,064 changes: 1,545 additions & 1,519 deletions scenes/Main.tscn

Large diffs are not rendered by default.

107 changes: 36 additions & 71 deletions scenes/NewsFeed.gd
Original file line number Diff line number Diff line change
@@ -1,44 +1,53 @@
extends RichTextLabel
extends ScrollContainer

const news_item = """
[url={link}]{title}[/url]
var news_item_scene = preload("res://scenes/NewsItem.tscn")

{author} - {date}
const news_cache_file = "user://news_cache.bin"

{contents}
[url={link}]{link}[/url]
======
"""

var images: Dictionary
var local_images : Dictionary

signal images_downloaded()
onready var feed_vbox = $Feed
onready var loading_text = $Feed/Loading

func _ready():
#connect("images_downloaded", self, "_on_images_downloaded")
_refresh_news()

# Updates display of news
func _refresh_news():
loading_text.show()
_update_news_feed(_get_news_cache())

$req.request("https://godotengine.org/news")
var response = yield($req,"request_completed")
_update_news_feed(_get_news(response[3]))

loading_text.hide()
var news = _get_news(response[3])
_save_news_cache(news)
_update_news_feed(news)

# Generates text bases on an array of dictionaries containing strings to
# interpolate
func _update_news_feed(feed : Array):
bbcode_text = "[center] === GODOTENGINE.ORG/NEWS ===[/center]\n\n"
var old_news = feed_vbox.get_children()
for i in range(2,old_news.size()):
old_news[i].queue_free()
for item in feed:
bbcode_text += news_item.format(item)
# parsing jpg buffer data currently not working.
# see https://github.com/godotengine/godot/issues/45523
#_download_images()

func _on_images_downloaded():
bbcode_text = bbcode_text.format(local_images)
var news_item = news_item_scene.instance()
feed_vbox.add_child(news_item)
news_item.set_info(item)

func _get_news_cache() -> Array:
var ret = []
var file = File.new()
if file.file_exists(news_cache_file):
file.open(news_cache_file, File.READ)
ret = file.get_var()
file.close()
return ret

func _save_news_cache(news : Array):
var file = File.new()
file.open(news_cache_file, File.WRITE)
file.store_var(news)
file.close()

# Analyzes html for <div class="news-item"> elements
# which will be further parsed by _parse_news_item()
Expand Down Expand Up @@ -96,17 +105,12 @@ func _parse_news_item(buffer, begin_ofs, end_ofs):
var url_end = image_style.find_last("'")
var image_url = image_style.substr(url_start,url_end - url_start)

# Images will be downloaded and their bbcode will be
# interpolated in a second pass so for now we store them
# as "{image#<hash of url>}"
var image_code = "image#%s" % image_url.hash()
parsed_item["image"] = "{%s}" % image_code
images[image_code] = image_url
parsed_item["image"] = image_url
parsed_item["link"] = xml.get_named_attribute_value_safe("href")
"h3":
if "title" in xml.get_named_attribute_value_safe("class"):
xml.read()
parsed_item["title"] = xml.get_node_data().strip_edges().to_upper() if xml.get_node_type() == XMLParser.NODE_TEXT else ""
parsed_item["title"] = xml.get_node_data().strip_edges() if xml.get_node_type() == XMLParser.NODE_TEXT else ""
"h4":
if "author" in xml.get_named_attribute_value_safe("class"):
xml.read()
Expand All @@ -122,42 +126,3 @@ func _parse_news_item(buffer, begin_ofs, end_ofs):

# Return the dictionary with the news entry once we are done
return parsed_item

# Downloads all image thumbnails for news snippets
func _download_images():
var dir = Directory.new()
dir.make_dir("user://images/")
var searches = 0
for img_id in images.keys():
while searches > 4: #four connections max
yield(get_tree().create_timer(0.1),"timeout")
searches += 1
var req = HTTPRequest.new()
add_child(req)

var local_path = "user://images/" + img_id
local_images[img_id] = "[img=50]%s%s[/img]" % [ local_path, ".tex" ]
req.request(images[img_id])
var response = yield(req,"request_completed")
if response[1] == 200:
_save_texture(response[3], local_path)
searches -= 1
req.queue_free()
emit_signal("images_downloaded")

func _save_texture(buffer : PoolByteArray, path: String):
var image = Image.new()
var error = image.load_jpg_from_buffer(buffer)
if error != OK:
print("Error %s loading jpg from buffer" % error)
return
else:
var texture = ImageTexture.new()
texture.create_from_image(image)
ResourceSaver.save(path + "tex",texture)

# Handle clicking on links
func _on_NewsFeed_meta_clicked(meta):
print(str(meta))
OS.shell_open(str(meta))

47 changes: 47 additions & 0 deletions scenes/NewsItem.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
extends VBoxContainer


var url = "https://example.com"

onready var title = $title
onready var author = $author
onready var thumb = $body/thumb_container/thumb
onready var contents = $body/contents

# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass


func _on_gui_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
OS.shell_open(url)

func set_info(info : Dictionary):
url = info.link
hint_tooltip = url
title.text = info.title
author.text = "%s (%s)" % [info.author, info.date]
contents.text = info.contents
_load_image(info.image)

func _load_image(url):
var local_path = "user://images/" + url.get_file()
var dir = Directory.new()
if not dir.file_exists(local_path):
$req.download_file = local_path
$req.request(url)
var response = yield($req,"request_completed")
if not response[1] == 200:
printerr("Could not find or download image")
return
var img = Image.new()
img.load(local_path)
var tex = ImageTexture.new()
tex.create_from_image(img)
thumb.texture = tex
74 changes: 74 additions & 0 deletions scenes/NewsItem.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
[gd_scene load_steps=3 format=2]

[ext_resource path="res://scenes/NewsItem.gd" type="Script" id=1]

[sub_resource type="StyleBoxFlat" id=1]
content_margin_left = 10.0
content_margin_right = 10.0
content_margin_top = 10.0
content_margin_bottom = 10.0
bg_color = Color( 0.2, 0.247059, 0.403922, 1 )
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5

[node name="NewsItem" type="VBoxContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
mouse_default_cursor_shape = 2
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource( 1 )

[node name="title" type="Label" parent="."]
margin_right = 1066.0
margin_bottom = 34.0
custom_colors/font_color = Color( 0.921569, 0.921569, 0.921569, 1 )
custom_styles/normal = SubResource( 1 )
text = "Title"
autowrap = true
uppercase = true

[node name="author" type="Label" parent="."]
margin_top = 38.0
margin_right = 1066.0
margin_bottom = 52.0
text = "Author"
autowrap = true

[node name="body" type="HBoxContainer" parent="."]
margin_top = 56.0
margin_right = 1066.0
margin_bottom = 600.0
size_flags_vertical = 3

[node name="thumb_container" type="CenterContainer" parent="body"]
margin_right = 100.0
margin_bottom = 544.0
rect_min_size = Vector2( 100, 100 )

[node name="thumb" type="TextureRect" parent="body/thumb_container"]
margin_top = 222.0
margin_right = 100.0
margin_bottom = 322.0
grow_horizontal = 2
grow_vertical = 2
rect_min_size = Vector2( 100, 100 )
size_flags_horizontal = 13
size_flags_vertical = 13
expand = true
stretch_mode = 7

[node name="contents" type="Label" parent="body"]
margin_left = 104.0
margin_right = 1066.0
margin_bottom = 544.0
rect_min_size = Vector2( 300, 0 )
size_flags_horizontal = 3
size_flags_vertical = 7
autowrap = true

[node name="req" type="HTTPRequest" parent="."]

[connection signal="gui_input" from="." to="." method="_on_gui_input"]

0 comments on commit da9b523

Please sign in to comment.